问题
I need to set up an <input type="text" />
so that it will accept only numeric chars, backspace, delete, enter, tabs and arrows.
There's a lot of exemple around there, i started with something similar to this:
function isNumericKeyCode (keyCode){
return ( (keyCode >= 48 && keyCode <= 57) //standard keyboard
||(keyCode >= 96 && keyCode <= 105)) //Numpad
}
$('#myTextBox').keydown(function(e){
var handled = true;
var keyCode = e.keyCode;
switch(keyCode){
//Enter and arrows
case 13:
case 37:
case 38:
case 39:
case 40:
doSomethingSpecialsWithThesesKeys();
break;
default:
handled = false;
break;
}
if ( !handled
&& keyCode !== 8 //backspace
&& keyCode !== 9 //tab
&& keyCode !== 46 //del
&& !isNumericKeyCode(keyCode)){
handled = true;
}
return handled;
});
All that worked perfectly until I hit the "#" key. In my french canadian keyboard, the "#" has his own key (no shift implied) that returns keyCode 51, the same as the number "3".
I think that in US keyboard, the "#" is obtained by pressing shift+3, that may be why they have the same keycode.
Now I realize that I have to handle the shift and alt keys too, but that's another story.
It works differently with the jquery keypress event, which offer the charCode property, but I did not used it at first because of what the documentation says :
as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
Also, I would need a workaround in that case to handle tabs, arrows and other special keys since they don't provide a charCode.
So the question is : is there a way to allow only some specifics chars using the keydown event? And that, in a way that will work independently of the keyboard layout?
As a side quest : Which browsers may be problematics with the keypress event? I mean, currently I don't really care if my website does not support IE6. I am targetting recent browsers.
Edit
As someone pointed out in the comments, this method does not allow user to "ctrl+v" a number in the input. In my particular case this is really not a requirement to be able to paste a number. But this popped something in my head, the user still can right-clic > copy some text in the input, and in that case that could be anything. The more I think of it, the more it seems to me that I will need the keydown
event to handle tabs and arrows, and another event to handle the input itself.
Edit2
A lot of beautiful answers here, but the award goes to mrtsherman for the use of input
and propertychange
events. I will use a combination of this answer for the numeric validation, plus the keyCode
event as before for the special use of arrows, tabs and enter keys.
回答1:
How about something like this. This should cover cut/paste and also rmb content. We monitor the textbox for any change in content. Then we use a regex to filter out characters based on a whitelist. This won't handle non-character key, but I think that is okay.
The \d
flag says that only digits should be accepted.
http://jsfiddle.net/UXeva/1
$('#myTextBox').bind('input propertychange', function() {
var text = $(this).val();
if (isNaN(text)) {
$(this).val(text.replace(/[^\d]/gi, ''));
}
});
We bind to two events here. input for FireFox and propertychange for other browsers.
回答2:
If older browsers are'nt an issue, the number input type should cover this.
<input type="number" />
If not you could use the isNaN javascript function
$("#number1").on('keyup', function() {
var myval = $(this).val();
if (isNaN(myval)) {
alert('numbers only!');
}
});
Personally I would do some regex filtering with a check to see if the value has changed, that will allow any character that does not change the value, like tabs, enter and arrows. With a regex you could also add or remove any character, or you could use \d for digits only or as below, [0-9]. Up to you really what your exact needs are?
var P;
$("#number2").on('keyup', function() {
var V = $(this).val();
if (V != P) {
$(this).val(V.replace(/[^0-9]/g,''));
}
P=V;
});
They could also be combined to something like this:
$("#number3").on('keyup', function() {
var V = $(this).val();
if (isNaN(V)) {
$(this).val(V.replace(/[^0-9]/g,''));
}
});
Here's a FIDDLE to test them out!
回答3:
Why not do something like this? It uses a combination of the keyup()
event and isNaN()
. It'll work whether the user types with the keyboard or pastes a number.
The way it works is, as soon as the text changes, it will check if the value is a number. If not, it will trim the input until it is a number. So, if you enter 25s
or 25ss
, you will be left with 25
.
This will work with ctrl+v
paste as well. It won't work with right-click paste and for that reason, I have disabled right-clicking only on the textbox.
Live Demo
The Jquery
$(document).ready(function(){
$('#number').keyup(function(){
var input = this.value;
while (isNaN(input))
{
input = input.substring(0,input.length-1);
$('#number').val(input);
}
});
$('#number').bind("contextmenu",function(e){
return false;
});
});
回答4:
jQuery also provides a shiftkey
boolean on the event object:
$('#myTextBox').keydown(function(e){
if(e.keyCode === 51 && !e.shiftKey){
// '3' key pressed while shift was **not** held down (not '#')
}
});
EDIT I reread your question and changed the code above for !shiftkey
来源:https://stackoverflow.com/questions/8904763/javascript-jquery-numeric-input-keycode-for-3-and-are-the-same