Javascript Regex to limit Text Field to only Numbers (Must allow non-printable keys)

80,831

Solution 1

The best method here is to use input event which handles all your concerns. It is supported in all modern browsers. With jQuery you can do like following. Handles all cases pasting the value with mouse/keyboard backspace etc.

$('.numeric').on('input', function (event) { 
    this.value = this.value.replace(/[^0-9]/g, '');
});

See it here

You can check if input event is supported by checking if the input has this property if not you can use onkeyup for older browsers.

if (inputElement.hasOwnProperty('oninput')) {
    // bind input
} else {
    // bind onkeyup
}

Solution 2

A nice solution is described in a previous post:

jQuery('.numbersOnly').keyup(function () { 
    this.value = this.value.replace(/[^0-9\.]/g,'');
});

Solution 3

Try it like,

CSS

.error{border:1px solid #F00;}

SCRIPT

$('#key').on('keydown',function(e){
    var deleteKeyCode = 8;
    var backspaceKeyCode = 46;
    if ((e.which>=48 && e.which<=57) ||
         (e.which>=96 && e.which<=105)  || // for num pad numeric keys
         e.which === deleteKeyCode || // for delete key,
             e.which === backspaceKeyCode) // for backspace
         // you can add code for left,right arrow keys
    {
        $(this).removeClass('error');
        return true;
    }
    else
    {
        $(this).addClass('error');
        return false;
    }
});

Fiddle: http://jsfiddle.net/PueS2/

Solution 4

Instead of checking for the event keyCode, why don't you just check for changes inside the actual input and then filter out non-numbers?

This example uses keyup so that it can read what was actually entered, which means the character is briefly displayed and then removed, but hopefully you get my gist. It might even give the user feedback that the character is not allowed. Either way I think this is the easiest setup, let me know if you need more help fleshing this out.

function filterNonDigits(evt)
{
  var event = evt || window.event;
  var val = event.target.value;
  var filtered = val.replace(/[^0-9]/g, '');

    if(filtered !== val) {
      event.target.value = filtered;
      event.target.className += " error";
    }
}

http://jsfiddle.net/mEvSV/1/

(jquery used solely to easily bind the keyup function, you won't need it for your actual script)

Share:
80,831
RMK
Author by

RMK

Software Developer / Software Development Analyst

Updated on July 15, 2022

Comments

  • RMK
    RMK almost 2 years

    I have received PHP/JS code from previous developer and I need to add number validation to a Mobile Number field. I already have the HTML validation in place but I need to add that if someone presses an invalid key, that it doesn't get displayed only to highlight the field later in red because it contains invalid input.

    I've seen many regex's used and tried them but they had an either/or effect from what I need which is: If a letter or special character is entered, do not accept and do not display, all other input (digits, keys) is accepted (I need the invalid character not be displayed at all, not displayed and then erased). The regex that is working the most now is this:

    function filterNonDigits(evt)
    {
      var event = evt || window.event;
      var keyentered = event.keyCode || event.which;
      keyentered = String.fromCharCode(keyentered);
    
      //var regex1 = /[0-9]|\./;
      var regex2 = /^[a-zA-Z.,;:|\\\/~!@#$%^&*_-{}\[\]()`"'<>?\s]+$/;
    
      if( regex2.test(keyentered) ) {
        event.returnValue = false;
        if(event.preventDefault) event.preventDefault();
      }
    

    When I used the commented regex1 (with the IF condition reversed), naturally it limited input to only digits thus preventing all keys such as Delete, BackSpace, etc. When using regex2, I still can't press Delete or the digits from the numpad.

    So my question is, can the above code be modified to accept only digits but also allow keys? Another important point is that I need a method that doesn't use keycodes (8, 24 etc) for those key, in order to make sure all keyboard types can be used.


    New Update:

    So my solution is as follows: If the "oninput" property exists, I use the solution provided by Ehtesham and if it doesn't, the backup uses the solution provided by Rohan Kumar. So it's something like this:

    if (obj.hasOwnProperty('oninput') || ('oninput' in obj)) 
    {
        $('#mobileno').on('input', function (event) { 
            this.value = this.value.replace(/[^0-9]/g, '');
        });
    } 
    else 
    {
        $('#mobileno').on('keypress',function(e){
            var deleteCode = 8;  var backspaceCode = 46;
            var key = e.which;
            if ((key>=48 && key<=57) || key === deleteCode || key === backspaceCode || (key>=37 &&  key<=40) || key===0)    
            {    
                character = String.fromCharCode(key);
                if( character != '.' && character != '%' && character != '&' && character != '(' && character != '\'' ) 
                { 
                    return true; 
                }
                else { return false; }
             }
             else   { return false; }
        });
    }
    

    Thanks.

  • Stephan Muller
    Stephan Muller over 10 years
    The regex includes a \., which OP explicitly listed in the disallow regex. Also, usually I wouldn't recommend a jQuery solution if the original post does not include jQuery in the question or tags.
  • RMK
    RMK over 10 years
    Thanks for the reply to both of you. I actually have tried this approach but was asked to find a way without the letter displaying and then erased which had me looking into other ways. Also jQuery is okay but I didn't include it since my question was more about the JS function to use.
  • RMK
    RMK over 10 years
    Thanks for the reply. As I mentioned in my comment on the previous reply, I have tried this approach but am looking for another precisely because of that "the character is briefly displayed and then removed" consequence.
  • Stephan Muller
    Stephan Muller over 10 years
    Ah, that calls for a different approach. Could you add that to your original question? It might prevent people from adding more answers that don't fit your needs.
  • RMK
    RMK over 10 years
    Thanks for the reply. My only issue with using keyCodes is if someone is using a non-US keyboard which may have different keyCodes for certain keys. I was looking into RegEx to avoid that issue.
  • Stephan Muller
    Stephan Muller over 10 years
    Oh but if that is the case, look at this: stackoverflow.com/questions/10531977/…. Just use the keypress event instead of keyup/down
  • RMK
    RMK over 10 years
    Thanks for the hint. I actually thought I had by mentioning that I don't want the invalid letter to display but I can see that it can be taken as it being ok if it displays and then is removed. I'll edit that now.
  • RMK
    RMK over 10 years
    Ah hadn't thought of that (newbie to JS and jQuery here). So would just substituting "keydown" with "keypress" in the code that Rohan Kumar has provided do the trick?
  • RMK
    RMK over 10 years
    I have another issue now though which is that the dot, % and & characters have the same codes as backspace and 2 of the arrow keys (which I allow) so dot, % and & are also accepted.. And one more thing which is in Mozilla FF, I can't type at all in the field. Any thoughts?
  • RMK
    RMK over 10 years
    Okay the FF issue is fixed, I had used "e.keyCode" instead of "e.which" which FireFox seems to have an issue with. Now I just have the problem of certain invalid characters that have the same code as non-printable keys. Ones I've noticed so far are (%,&,.,') Any idea how to work around that? Thanks.
  • Rohan Kumar
    Rohan Kumar over 10 years
    You can find the codes from api.jquery.com/event.which or cambiaresearch.com/articles/15/javascript-char-codes-key-cod‌​es with shift key and add them in if condition and if the keys is valid then it will shown in input box otherwise the input box would be red as shown in fiddle also e.which works in FF and e.keyCode works in some browsers like IE You cn use it like var keyunicode=e.charCode || e.keyCode and use keyunicode in if condition
  • RMK
    RMK over 10 years
    Thanks for the links and the tips about browser compatibility. So I'll add what I have so far to the OP, it works well on first testing, any improvements or optimizations?
  • RMK
    RMK over 10 years
    Thanks for the reply, this actually looks promising for what I need. How would I get "inputElement"? Would "document.getElementById" work ? Edit1: I tried it and it's returning False in FF24.0 and IE10. Is that normal behaviour? Edit2: I think adding (hasOwnProperty || 'property' in inputElement) might be a good idea for browsers where hasOwnProperty is not supported. Does that work?
  • RMK
    RMK over 10 years
    Okay great thanks, this seems to be working great so far. One small issue, if I have my cursor in the middle of the filed value and I press on an invalid character, the cursor moves to the end of field. This also happens in Chrome when I try to delete a character in the middle. Can anything be done about that or is it normal?
  • RMK
    RMK over 10 years
    I've used this method as backup in my solution so I will upvote as soon as I have enough reputation. Thanks.
  • RMK
    RMK over 10 years
    Thank you for your help in the different issues that came up while I was trying out the different solutions provided :)
  • Pranesh Janarthanan
    Pranesh Janarthanan about 5 years
    @Ehtesham, I tried your code there is a bug with respect to mobile browser usage. Can u help me resolve it? Problem: after typing numbers, if i press spacebar it erases the typed number!. how to fix this?
  • jlc488
    jlc488 over 2 years
    @RMK use input event instead of keyup or keydown