Best way to restrict a text field to numbers only?

163,964

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

http://jsfiddle.net/zpg8k/

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

http://jsfiddle.net/PgHFp/

<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.

Share:
163,964

Related videos on Youtube

RobHardgood
Author by

RobHardgood

Updated on August 29, 2021

Comments

  • RobHardgood
    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
      Sikshya Maharjan over 13 years
      If you're happy using HTML 5, imperfectly implemented, form type <input type="number" /> that can work.
    • RobHardgood
      RobHardgood over 13 years
      I 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
      Pineda over 7 years
  • RobHardgood
    RobHardgood over 13 years
    Hmm, 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
    Robert over 13 years
    It'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
    sod over 13 years
    It allows because someone messes around with his jsfiddle. Paste his javascript and you get what you want.
  • RobHardgood
    RobHardgood over 13 years
    Ohh, 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
    Robert over 13 years
    The 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
    RobHardgood over 13 years
    Great! I think this will work perfectly :) thanks for explaining it too.
  • RobHardgood
    RobHardgood over 13 years
    This works great too! Thanks @fahd it even prevents pasting text
  • Robert
    Robert over 13 years
    Keep in mind it won't prevent dragging text into the textbox, hence the need for onsubmit and server side verification.
  • Robert
    Robert over 13 years
    @fahd: As noted in the "make sure you verify server and on submit".
  • RobHardgood
    RobHardgood over 13 years
    @Robert Indeed, I always have PHP form validation in case users have javascript turned off anyway.
  • RobHardgood
    RobHardgood over 13 years
    Sorry 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
    Tim Down over 13 years
    Don't use keydown or keyup 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 is keypress.
  • Robert
    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
    Tim Down over 13 years
    One other issue: in IE up to and including version 8, arrays don't have an indexOf method.
  • Robert
    Robert over 13 years
    Hmm @Tim Down, full of helpful tidbits that make me hate IE more, adjusted again.
  • Robert
    Robert over 13 years
    What browser commands? I can still backspace etc etc. Which command specifically?
  • RobHardgood
    RobHardgood over 13 years
    I'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
    Robert over 13 years
    Hmm 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
    RobHardgood over 13 years
    Interesting... I just tried it in Opera and Safari too, and it works in Opera but not Safari.
  • RobHardgood
    RobHardgood over 13 years
    Also, 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
    Robert over 13 years
    I 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 except e.preventDefault(); would change to return false;
  • RobHardgood
    RobHardgood over 13 years
    Ah, I see. Thanks. Let me know if you think of a solution for this firefox thing...
  • RobHardgood
    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
    RobHardgood over 13 years
    For 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
    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
    Tim Down over 13 years
    Good point. I've updated my answer to check for the Ctrl key being pressed.
  • Tim Down
    Tim Down over 13 years
    Robert, you can entirely reliably distinguish between t and Ctrl-t using the ctrlKey property of the event.
  • Robert
    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
    Tim Down over 13 years
    Really? It works fine for me on my Mac. What are you pressing and what's going wrong?
  • Tim Down
    Tim Down over 13 years
    Yes. Cmd-T works fine for me within the input in Firefox 3.6.
  • Robert
    Robert over 13 years
    Hmm, I made another jsfiddle again to test it and it's working now, maybe I copied something wrong... oh well.
  • Matt Johnson-Pint
    Matt Johnson-Pint about 11 years
    This 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
    th3byrdm4n about 11 years
    I am befuddled that it's not included in the top answer. Perhaps an edit is necessary?
  • Whimsical
    Whimsical about 11 years
    perfect ! Exactly what i was looking for. Shift+1 was still coming up
  • wOlVeRiNe
    wOlVeRiNe over 10 years
    I 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.
    Volker E. about 10 years
  • Casey
    Casey almost 10 years
    This is fantastic, although it could use a little explanation of what's going on.
  • Admin
    Admin almost 10 years
    Check for NULL character then tests on digit regex "/\d/"
  • user3591637
    user3591637 over 9 years
    late comment: but how would you be able to make it enter float like .5 ect.?
  • Enzero
    Enzero over 9 years
    @TimNguyen the float isn't working it is accepting all characters
  • Emi
    Emi about 9 years
    This was the only solution that works on all platforms. Thank you for being awesome!
  • Arkadiusz Rosłaniec
    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
    David about 8 years
    This 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
    Andy G about 8 years
    This looks good to me, although event.which is preferred to normalize the key codes.
  • Andy G
    Andy G about 8 years
    (I should say, the code looks good for my purpose, unfortunately not the OP's requirement though ;))
  • ERR
    ERR over 7 years
    How can we include negative sign in this case?
  • Hamund
    Hamund over 7 years
    Try testing on a characterset of digits and minus sign like this: ... || /[\d-]/.test(...
  • Damien
    Damien over 6 years
    With this solution we can still paste text in the field (Ctrl+V).
  • Damien
    Damien over 6 years
    Nice, but we can't "TAB" out of the field, select everything with Ctrl+A... so it does not answer the question completely.
  • vibs2006
    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.