Most web developers know that to restrict only numbers to a form input, you can do something like this:
$(function() {
$("#foobar").keypress(function(e) {
if($.inArray(e.which, range(48, 57)) == -1) {
e.preventDefault();
return false;
}
});
});
function range(start, end) {
var range = [];
for(var i = start; i <= end; i++) {
range.push(i);
}
return range;
}
Unfortunately, this does not quite get the job done on an Android with the default browser. (iPhone and Other Android browsers have not been tested, so they could suffer from the same issue. Tested on an iPhone 4S, which did not have this issue.)
On an Android, let's say you first type "f". Nothing happens. Awesome. Wait just a minute. You then type "a". What happens? The "f" is put into the input field! You type "c", the "a" is put into the field. And so on. Whatever the previously-entered character is, that's what's put into the field.
Here's a jsFiddle that demonstrates the issue.
The fiddle works fine on a desktop, but try it on Android (phone or emulator). I've tested with Android 2.3.6 and 2.2.
Anyone run into this before? Any direction would be greatly appreciated! For now, the workaround is to remove non-numeric characters immediately afterwards (in the keyup
event).
Update: Here is a fiddle that shows that preventDefault()
is being reached. The problem seems to be that rather than preventing, it's simply delaying (until the next event).
an
only a
is displayed, I tap Android
and it fills in Androi
. It would seem only the last letter is seen & processed. Not to dissimilar to the paste event (which also would allow entering invalid characters) - Chris Chilvers 2012-06-13 10:56
<input type="number">
as @keystorm describes in his answer below. It's a shame this issue exists. If you end up finding an actual solution please come back and post here - The Awnry Bear 2013-05-02 16:15
A completely different approach would be using <input type="number">
and relying on the browser to provide the appropriate interface/filtering (which mobile browsers are prone to). It does not fix the code, but should circumvent the problem, which looks like a bug, to be honest.
A wild guess: Maybe Androids register the input at the keydown
stage. You could try both events.
Ok I played with this a bit and this is running fine on my andriod:
var reserved = [0,8]
$(function()
{
$("#foobar").keypress(function(e)
{
if($.inArray(e.which, reserved) < 0 && ((e.which < 48) || (e.which > 57)))
{
e.preventDefault();
return false;
}
});
});
http://jsfiddle.net/HW794/1/embedded/result/
Possible that droid does not like the call to the fn? (range)