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

RMK picture RMK · Sep 30, 2013 · Viewed 76.3k times · Source

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.

Answer

Ehtesham picture Ehtesham · Oct 1, 2013

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
}