Best way to restrict a text field to numbers only?
Solution 1
This is something I made another time for just numbers, it will allow all the formatters as well.
jQuery
$('input').keypress(function(e) {
var a = [];
var k = e.which;
for (i = 48; i < 58; i++)
a.push(i);
if (!(a.indexOf(k)>=0))
e.preventDefault();
});
Try it
As a note, you'll want to filter on submit/server side as well, for sake of pasting/context menu and browsers that don't support the paste event.
Edit to elaborate on multiple methods
I see you're bouncing around the 'accepted' answer, so I'll clear something up. You can really use any of the methods listed here, they all work. What I'd personally do is use mine for live client side filtering, and then on submit and server side use RegEx as suggested by others. However, no client side by itself will be 100% effective as there is nothing stopping me from putting document.getElementById('theInput').value = 'Hey, letters.';
in the console and bypassing any clientside verification (except for polling, but I could just cancel the setInterval
from the console as well). Use whichever client side solution you like, but be sure you implement something on submit and server side as well.
Edit 2 - @Tim Down
Alright, per the comments I had to adjust two things I didn't think of. First, keypress instead of keydown, which has been updated, but the lack of indexOf in IE (seriously Microsoft!?) breaks the example above as well. Here's an alternative
$('input').keypress(function(e) {
var a = [];
var k = e.which;
for (i = 48; i < 58; i++)
a.push(i);
if (!($.inArray(k,a)>=0))
e.preventDefault();
});
New jsfiddle: http://jsfiddle.net/umNuB/
Solution 2
This works in IE, Chrome AND Firefox:
<input type="text" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));" />
Solution 3
.keypress(function(e)
{
var key_codes = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 8];
if (!($.inArray(e.which, key_codes) >= 0)) {
e.preventDefault();
}
});
You need Backspace and Delete keys too ;)
Solution 4
<html>
<head>
<title>Test</title>
<script language="javascript">
function checkInput(ob) {
var invalidChars = /[^0-9]/gi
if(invalidChars.test(ob.value)) {
ob.value = ob.value.replace(invalidChars,"");
}
}
</script>
</head>
<body>
<input type="text" onkeyup="checkInput(this)"/>
</body>
</html>
Solution 5
I use this:
oEl.keypress(function(ev)
{
var sKey = String.fromCharCode(ev.which);
if (!sKey.match(/[0-9]/) || !sKey === "")
ev.preventDefault();
});
The advantage is, that every key which does not provide an input to the field is still allowed, so you don't have to worry about every single special key. Even combos like CTRL + R do still work.
EDIT As this is not working in Firefox I had to modify the function a little:
oEl.keypress(function(ev)
{
var iKeyCode = ev.which || ev.keyCode;
var aSpecialKeysForFirefox = [8, 9, 13, 27, 37, 38, 39, 40, 46];
var sKey = String.fromCharCode(iKeyCode);
if (sKey !== "" && $.inArray(iKeyCode, aSpecialKeysForFirefox ) < 0 && !sKey.match(/[0-9]/)) {
ev.preventDefault();
}
});
Explanation All Browsers handle jquerys keypress event differently. To make it work in FF the $.inArray check is added. As firefoxs keypress-event doesn't trigger when combinations like strg+tab are used, but the others do, the key.match approach still adds a little value to the latter, as it enables those combinations.
Related videos on Youtube
RobHardgood
Updated on August 29, 2021Comments
-
RobHardgood almost 3 years
I'm using the following Javascript to restrict a text field on my website to only accept numerical input, and no other letters or characters. The problem is, it REALLY rejects all other key inputs, like ctrl-A to select the text, or even any other browser functions like ctrl-T or ctrl-W while the text box is selected. Does anyone know of a better script to only allow numerical input, but not block normal commands (that aren't being directly input into the field)? Thanks Here is the code I'm using now:
function numbersonly(e, decimal) { var key; var keychar; if (window.event) key = window.event.keyCode; else if (e) key = e.which; else return true; keychar = String.fromCharCode(key); if ((key==null) || (key==0) || (key==8) || (key==9) || (key==13) || (key==27)) return true; else if ((("0123456789").indexOf(keychar) > -1)) return true; else if (decimal && (keychar == ".")) return true; else return false; }
Edit: None of the solutions provided have solved my problem of allowing commands like ctrl-A while the text box is selected. That was the whole point of my asking here, so I have gone back to using my original script. Oh well.
-
Sikshya Maharjan over 13 yearsIf you're happy using HTML 5, imperfectly implemented, form type
<input type="number" />
that can work. -
RobHardgood over 13 yearsI wish i could use HTML 5. That was my first thought, and it would have saved me so much time looking up javascript :-p thanks anyway
-
Pineda over 7 yearsPossible duplicate of HTML Text Input allow only Numeric input
-
-
RobHardgood over 13 yearsHmm, I'm not sure this will work for me. It still seems to allow letters if you hold down the key. I want to prevent letters entirely, so that a form validation error is the last resort
-
Robert over 13 yearsIt's not allowing letters for me. As I said this was something I built before that had letters as well, but I removed that portion, make sure you're looking at the right jsfiddle.
-
sod over 13 yearsIt allows because someone messes around with his jsfiddle. Paste his javascript and you get what you want.
-
RobHardgood over 13 yearsOhh, I see. You're right, I didn't notice the code was different. Can you explain what all those numbers are for var a? Are they the key codes for the numerical keys?
-
Robert over 13 yearsThe numbers are the formatters, backspace, shift etc etc etc. As you press a key it should show the keycode to the right, so you can play around and see what you want to allow and disallow.
-
RobHardgood over 13 yearsGreat! I think this will work perfectly :) thanks for explaining it too.
-
RobHardgood over 13 yearsThis works great too! Thanks @fahd it even prevents pasting text
-
Robert over 13 yearsKeep in mind it won't prevent dragging text into the textbox, hence the need for onsubmit and server side verification.
-
Robert over 13 years@fahd: As noted in the "make sure you verify server and on submit".
-
RobHardgood over 13 years@Robert Indeed, I always have PHP form validation in case users have javascript turned off anyway.
-
RobHardgood over 13 yearsSorry for the checkmark switching, I didn't realize you could only mark one (i'm a new member) but I'm using this solution. Thanks again Robert
-
Tim Down over 13 yearsDon't use
keydown
orkeyup
for checking the character the user has typed. Any success you get will be coincidental and unreliable: a differently laid out keyboard or a keyboard from a culture other than your own will have different key mappings and your key codes will be useless. The only event that contains character information iskeypress
. -
Robert over 13 years@Tim Down: A very valid point, I didn't think of that. Updated answer, hopefully Rob sees the notification.
-
Tim Down over 13 yearsOne other issue: in IE up to and including version 8, arrays don't have an
indexOf
method. -
Robert over 13 yearsHmm @Tim Down, full of helpful tidbits that make me hate IE more, adjusted again.
-
Robert over 13 yearsWhat browser commands? I can still backspace etc etc. Which command specifically?
-
RobHardgood over 13 yearsI'm talking about ctrl-A to highlight all the text in the field, and ctrl-T to open a new tab, etc. Usually they work find inside text fields. Using firefox
-
Robert over 13 yearsHmm they still work in Chrome, but not FireFox. It appears to be the way that FireFox handles the events, with Chrome intercepting the event before it's passed to the form, but Firefox not. I'll have to think a bit of a way to get around that...
-
RobHardgood over 13 yearsInteresting... I just tried it in Opera and Safari too, and it works in Opera but not Safari.
-
RobHardgood over 13 yearsAlso, what do you think would be the best way to call this function from my <input type="text"> tag? Or should it load when the page loads? I'm still kind of new to JS...
-
Robert over 13 yearsI don't think there's a way around the FireFox problem because FireFox fires the event to the input as if it was just the key being pressed, not ctrl+key. As far as implementation, this uses a jQuery selector, so you'd use a selector equivalent to your input element. Non-jQuery would be something like
document.getElementById('elementId').onkeypress = function() {
then the rest stays the same excepte.preventDefault();
would change toreturn false;
-
RobHardgood over 13 yearsAh, I see. Thanks. Let me know if you think of a solution for this firefox thing...
-
RobHardgood over 13 years@Tim Down this works well too, but again, it won't allow me to use functions like ctrl-A within the text box
-
RobHardgood over 13 yearsFor some reason, this isn't working when I use onkeyup... It works great when I use onkeypress, but that makes it check a character too late...
-
Robert over 13 years@RobHargood, my comment explained why that's so, because Firefox passes ctrl-t etc etc as if you're pressing just t, there's no reliable way to completely block the t letter in Firefox while allowing control-t. You can be reactive instead of proactive if you want that functionality, using
replace
like some of the other examples here. -
Tim Down over 13 yearsGood point. I've updated my answer to check for the Ctrl key being pressed.
-
Tim Down over 13 yearsRobert, you can entirely reliably distinguish between
t
andCtrl-t
using thectrlKey
property of the event. -
Robert over 13 years@TimDown, it's not working for me even when checking for control, Firefox on Mac for me is firing into the textfield as if it was only t being pressed.
-
Tim Down over 13 yearsReally? It works fine for me on my Mac. What are you pressing and what's going wrong?
-
Tim Down over 13 yearsYes. Cmd-T works fine for me within the input in Firefox 3.6.
-
Robert over 13 yearsHmm, I made another jsfiddle again to test it and it's working now, maybe I copied something wrong... oh well.
-
Matt Johnson-Pint about 11 yearsThis only works for fixed-length fields. For example, if you might store numbers from 1 to 1000, your users would have to type
0001
. Not so friendly for that. Maybe for phone numbers, SSNs, etc. -
th3byrdm4n about 11 yearsI am befuddled that it's not included in the top answer. Perhaps an edit is necessary?
-
Whimsical about 11 yearsperfect ! Exactly what i was looking for. Shift+1 was still coming up
-
wOlVeRiNe over 10 yearsI have 2 points, 1) Your code doesn't work on an Android Phone 2) You have written a loop inside a keypress event. So every time i hit a key, it'll iterate through the loop. Either shift your loop outside the keypress event or just do something what "hofnarwillie" mentioned
-
Volker E. about 10 yearsjQuery for the win!? meta.stackexchange.com/questions/19478/the-many-memes-of-meta/… ;)
-
Casey almost 10 yearsThis is fantastic, although it could use a little explanation of what's going on.
-
Admin almost 10 yearsCheck for NULL character then tests on digit regex "/\d/"
-
user3591637 over 9 yearslate comment: but how would you be able to make it enter float like .5 ect.?
-
Enzero over 9 years@TimNguyen the float isn't working it is accepting all characters
-
Emi about 9 yearsThis was the only solution that works on all platforms. Thank you for being awesome!
-
Arkadiusz Rosłaniec almost 9 years
.on('keypress', function (event) { var _element = $(this), keyCode = event.keyCode || event.which, keysAllowed = [44, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 8, 9, 13]; if ($.inArray(keyCode, keysAllowed) === -1 && event.ctrlKey === false) { event.preventDefault(); } });
it also add tab and enter and watch for ctrl combination. -
David about 8 yearsThis does not account for the shift key being held on US keyboards and it also disables the backspace key, which is not a desired effect.
-
Andy G about 8 yearsThis looks good to me, although event.which is preferred to normalize the key codes.
-
Andy G about 8 years(I should say, the code looks good for my purpose, unfortunately not the OP's requirement though ;))
-
ERR over 7 yearsHow can we include negative sign in this case?
-
Hamund over 7 yearsTry testing on a characterset of digits and minus sign like this: ... || /[\d-]/.test(...
-
Damien over 6 yearsWith this solution we can still paste text in the field (Ctrl+V).
-
Damien over 6 yearsNice, but we can't "TAB" out of the field, select everything with Ctrl+A... so it does not answer the question completely.
-
vibs2006 over 6 years@Damien we can also easily do that by handling keyboard and mouse events. I have kept the example simple for sake of simplicity.