How do you programmatically select the text of an input field on iOS devices, e.g. iPhone, iPad running mobile Safari?
Normally it is sufficient to call the .select() function on the <input ... /> element, but this does not work on those devices. The cursor is simply left at the end of the existing entry with no selection made.
input.setSelectionRange(0, 9999);
https://developer.mozilla.org/en/DOM/Input.select
Nothing in this thread worked for me, here's what works on my iPad:
// t is the input field
setTimeout(function() {
t.setSelectionRange(0, 9999);
}, 1);
See this fiddle: (enter some text in the input box and click 'select text')
It is selecting text in an inputbox on my iPod (5th gen iOS6.0.1), opening the keyboard and also showing the Cut/Copy/Suggest... menu
Using plain javascript. Did not try this with jQuery
document.getElementById("p1").selectionStart = 0
document.getElementById("p1").selectionEnd = 999
Note that the number 999 is just a sample. You should set these numbers to the number of characters you want to select.
UPDATE:
iPod5 - iOS6.0.1 - Working ok.
iPad1 - iOS5.1.1 - Only text selected. Tap selection once to open Cut/Copy menu
iPad2 - iOS4.3.3 - Only text selected. Tap selection once to open Cut/Copy menu
For the last two, you might experiment by triggering a click event on the input element
UPDATE: (07-10-2013)
iPod5 - iOS7.0.2 - Using the fiddle in the link: Can't see typed text in input box.
Pressing select redirects me to facebook.com (??? wtf ???)
no idea what's going on there.
UPDATE: (14-11-2013)
iOS 7.0.3 : Thanks to the comment from binki update that the
.selectionStart and .selectionEnd does work.
UPDATE: (15-01-2015)
iOS 8.x.x : Thanks to the comment from Michael Siebert. Taken from the comment:
I had to listen for both focus AND click events and then setTimeout/_.debounce
to make it work in both cases: click the input or focus through tabbing
It's hard to prove a negative, but my research suggests this is a bug in Mobile Safari.
Note that focus() works, more or less—though it can require more than one tap to succeed, and it's not necessary if you're trying to respond to a user tap on the field in question as the tap itself will give the field focus. Unfortunately, select() is simply non-functional in Mobile Safari.
Your best bet may be a bug report with Apple.
Sorry, in my earlier post, I didn't notice the Javascript implying that you wanted an answer in Javascript.
To get what you want in UIWebView with javascript, I have managed to scrape together two important pieces of info to get it to work. Not sure about the mobile browser.
element.setSelectionRange(0,9999); does what we want
mouseUp event is undoing the selection
Thus (using Prototype):
input.observe('focus', function() {
this.setSelectionRange(0, 9999);
});
input.observe('mouseup', function(event) {
event.stop();
});
does the trick.
Matt
It looks like focus will work but only when directly called from a native event. calling focus using something like SetTimeout does not appear call up the keyboard. Control of the ios keyboard is very poor. Its not a good situation.
I went nuts looking for this solution, while all your responses did help it opened another can of worms for me.
The client wanted the user to be able to click and select all, and also let the user 'tab' and select all on the iPad (with an external keyboard. I know, crazy...)
My solution to this problem was, rearrange the events. First Focus, then Click, then touchstart.
$('#myFUBARid').on('focus click touchstart', function(e){
$(this).get(0).setSelectionRange(0,9999);
//$(this).css("color", "blue");
e.preventDefault();
});
I hope this helps someone, as you lot have helped me countless times.
Something like the following is working for me for me on Webkit that comes with Android 2.2:
function trySelect(el) {
setTimeout(function() {
try {
el.select();
} catch (e) {
}
}, 0);
}
See Chromium Issue 32865.
With iOS 7 on iPad the only way that I was able to make this work was to use actually <textarea></textarea> instead of <input> field.
e.g.
<textarea onclick="this.setSelectionRange(0, 9999);">My text will be selected when textarea is clicked.</textarea>
How to prevent user from changing text inside area was more difficult, since is you make textarea readonly the selection trick won't work anymore.
If you are using HTML5-compliant browsers, you can use placeholder="xxx" in your input tag.
That should do the job.
Related
Imagine this codepen: https://codepen.io/anon/pen/awoXKv
As you can see, I got an input field inside my a element. (This cannot be changed currently). What I want to do, that when I click the input, the input gets focused and I don't get redirected.
The above snippet does exactly this in Chrome/Firefox. But now, I tested it on IE and am experiencing an issue, that the input only gets focused, if I use double click.
I tried to focus it manually by using this $(e.currentTarget).find('input').focus();, but this didn't help. Som eother StackOverflow thread said, this is because IE lazy loads the events and I have to use a timeout fucntion
setTimeout(function () {
$(e.currentTarget).find('input').focus();
}, 100);
But even this didn't work. How can I focus an input behind an a tag in IE?
Update:
Doesn't seem like a focus problem, because when I use alert($(e.currentTarget).find('input').is(':focus')); it returns true. What else could be the problem here?
I wrote small function. When i type something in input (text input) and then click on this input, all text highlights, so user can delete long text, without typing backspace many times.
$('.search').mouseup(function(){
var save_this = $(this);
save_this.select();
save_this.setSelectionRange(0, 9999);
});
This works well for android and desktop, but not for IOS. Any ideas ?
Here i see, that on IOS while on click from, or to, text is selected.
I think you should listen to touchend event on mobile devices instead of mouseup.
Consider this Example.
The essential bit is the JavaScript:
function encodeInput(editor) {
theText = editor.val();
theText = theText.replace(/\*\*\*(.*?)\*\*\*/, '<strong><i>$1</i></strong>', 'g');
theText = theText.replace(/\*\*(.*?)\*\*/, '<strong>$1</strong>', 'g');
theText = theText.replace(/\*(.*?)\*/, '<i>$1</i>', 'g');
console.log(theText);
$('#preview').html(theText);
}
$(function() {
$editor = $('#editor');
$editor.keyup(function() {
encodeInput($(this));
});
});
Tested and works great (I do need the \*\*\* part or it doesn't work).
Anyways, on to the main course
The Problem
Because I'm using keyup, the script is not very responsive (eg. it only "runs" once the user had let go of the key). I want it to behave more like the editor here on StackOverflow, where the key is pressed and response occurs immidiately.
I tried using keydown and keypress but it seems as if the val() attribute is not updated when it runs, so I can't really know the updated value.
In Short
How can I make it more responsive, so that when the user pressed a key, the preview is automatically updated??
You can use the HTML5 input event in most browsers and the propertychange event in IE < 9. These events fire immediately after the textarea's value is updated.
Here's an updated demo using these events:
http://jsfiddle.net/muWm2/1/
I've written about this in a few places on SO. Here are two of them:
Catch only keypresses that change input?
jQuery keyboard events
I would recommend against updating the preview on every single change to the textarea's value because it could quickly get unresponsive, which is a big no-no for user experience. I'd suggest "debouncing" the event, in this case waiting for a period of user inactivity (say half a second) before updating the preview. Here's an answer and a link that may help:
How to trigger an onkeyup event that's delayed until a user pauses their typing?
Debouncing Javascript Methods by John Hann
You can bind() both the keyup and keydown events:
$editor.bind('keyup keydown', function() {
encodeInput($(this));
});
I noticed that only the first occurrence was working, adding the g flag to the regex seemed to help, and for the purpose of the jsfiddle demo only, unchecking "normalize css" made the bold text appear.
http://jsfiddle.net/tuUym/3/
Keypress fires when the key is pressed continously, so you have to bind it to keypress in order to see the result. And thats it.
http://jsfiddle.net/tuUym/4/
UPDATE: I see what you mean. Maybe you need an input poller? Check out the de obfuscated wmd code. That will help you achieve the lagless editor you aim for:
WMD Download
I am unable to detect when input type="file" changes its value after user selects file and the dialog box closes.
$('.myInput').change(function(){
alert($(this).val());
})
Above jQuery code works perfectly in all browsers apart from IE. For some reason IE detects the change only after input field loses focus.
Is there a way to detect the change immediately after dialog box closes? Or maybe to force input field to lose focus after dialog box closes so IE can detect it?
I'm puzzled. Thanks for any help.
This was a known bug that was resolved as part of the jQuery 1.4.2 release, 1.4.2 got a major event model re-write and this was fixed as part of that, just upgrade to resolve the problem :)
Edit - Nick is right, it's fixed in 1.4.2. http://jsfiddle.net/7wR2L/
You can detect click and keep track of it's last value. Something like..
$('.myInput').click(function() {
var $file = $(this);
if( $file.val() != $file.data('lastVal') ) {
// different
}
$file.data('lastVal', $file.val() );
});
Dan Heberden's comment about updating to 1.4.2 works.
However if another element is used to trigger the file file selection, the file input element no longer registers a "change" event.
The new question I created for this has a fork your fiddle to illustrate this case. See jQuery: "change" event on file input element does not fire if the file selection is triggered by an element other than the file input for details.
Because of the issue explained in this question I have a situation where I need to attach the mousewheel event to the drop down list only when it is expanded (I do this in the onclick event). However I need to remove the mousewheel event when the list collapses. How do I go about detecting this?
I can't just use the onchange event because the user may not have actually changed their selection. I've tried the onblur event but in most browsers (except IE) the drop list stays focused when the list is collapsed.
Cheers.
var list = document.getElementById("list");
list.onclick = function (e) {
// attach mousewheel
list.onmousewheel = function (e) {
// ...
}
// attach click off
// This event fires fine in all browsers except FF when the list is expanded.
// In firefox it only fires when anywhere in the document is clicked twice.
// The first click closes the drop down list as expected and the second one
// fires the event.
window.document.onclick = function (e) {
list.onmousewheel = null;
window.document.onclick = null
}
};
EDIT:
Unfortunately meder's solution doesnt work in firefox. The click event on the document doesn't get fired until i click twice off the drop down list. How do I get around that? It works fine in IE.
EDIT2:
I've done some more testing and the following browsers behave as expected
IE 7,
Chrome 3
Opera 10
Firefox requires 2 clicks in the window to make it work & Safari doesn't work at all.
It appears that even when you click off the drop down list firefox maintains focus on it. It's not until the second click occurs that the drop down list eventually loses it's focus.
Are you looking for something like this? If the user clicks anywhere that's not within #el, it will branch out and you can do what you want, though this requires jQuery but it would take far too many lines of DOM Scripting.
var dropdown = $('#el');
$(document).click(function(e){
if ( (!$(e.target).is(dropdown)) || !$(e.target).closest('#el').length ) {
// do what you need to
}
});
If not, can you be more specific and include an example?
PS - I did not test the snippet, sorry if it isn't what you want.
OK, I still have no idea what you're trying to achieve with such a tightly-scripted select box, but in general trying to change the internal working of a native <select> isn't fruitful. There's no standard that says how events flow internally to the form element, and browsers that implement select as an OS-level widget (IE) can't do much to support it anyway.
If you must have this behaviour, I'd suggest using scripting to replace the <select> box on-fly with a JavaScript-powered analogue made out of <div>s. Then you can control exactly how each mouse and keyboard interaction behaves. There are many libraries that do this already, though again if you need to be very specific about the exact behaviour they might not suit you.