HTML text input allow only numeric input

HTML text input allow only numeric input

Is there a quick way to set an HTML text input () to only allow numeric keystrokes (plus ‘.’)?

Solutions/Answers:

Solution 1:

JavaScript

Note: This is an updated answer. Comments below refer to the old version which messed around with keycodes.

The setInputFilter function from the below script allows you to use any kind of input filter on a text <input>, including various numeric filters. This will correctly handle Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the cursor position, all keyboard layouts and all browsers since IE 9. Note that you still must do server side validation!

Try it yourself on JSFiddle.

// Restricts input for the given textbox to the given inputFilter.
function setInputFilter(textbox, inputFilter) {
  ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function(event) {
    textbox.addEventListener(event, function() {
      if (inputFilter(this.value)) {
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      } else if (this.hasOwnProperty("oldValue")) {
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      }
    });
  });
}

Usage:

// Restrict input to digits and '.' by using a regular expression filter.
setInputFilter(document.getElementById("myTextBox"), function(value) {
  return /^\d*\.?\d*$/.test(value);
});

Some input filters you might want to use:

  • Integer values (both positive and negative):
    /^-?\d*$/.test(value)
  • Integer values (positive only):
    /^\d*$/.test(value)
  • Integer values (positive and up to a particular limit):
    /^\d*$/.test(value) && (value === "" || parseInt(value) <= 500)
  • Floating point values (allowing both . and , as decimal separator):
    /^-?\d*[.,]?\d*$/.test(value)
  • Currency values (i.e. at most two decimal places):
    /^-?\d*[.,]?\d{0,2}$/.test(value)
  • Hexadecimal values:
    /^[0-9a-f]*$/i.test(value)

jQuery

There is also a jQuery version of this. See this answer or try it yourself on JSFiddle.

HTML 5

HTML 5 has a native solution with <input type="number"> (see the specification), but note that browser support varies:

  • Most browsers will only validate the input when submitting the form, and not when typing.
  • Most mobile browsers don’t support the step, min and max attributes.
  • Chrome (version 71.0.3578.98) still allows the user to enter the characters e and E into the field. Also see this question.
  • Firefox (version 64.0) and Edge (EdgeHTML version 17.17134) still allow the user to enter any text into the field.

Try it yourself on w3schools.com.

More complex validation options

If you want to do some other validation bits and pieces, this could be handy:

Solution 2:

Use this DOM

<input type='text' onkeypress='validate(event)' />

And this script

function validate(evt) {
  var theEvent = evt || window.event;

  // Handle paste
  if (theEvent.type === 'paste') {
      key = event.clipboardData.getData('text/plain');
  } else {
  // Handle key press
      var key = theEvent.keyCode || theEvent.which;
      key = String.fromCharCode(key);
  }
  var regex = /[0-9]|\./;
  if( !regex.test(key) ) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
  }
}

Solution 3:

I’ve searched long and hard for a good answer to this, and we desperately need <input type="number", but short of that, these 2 are the most concise ways I could come up with:

<input type="text" 
       onkeyup="this.value=this.value.replace(/[^\d]/,'')">

If you dislike the non-accepted character showing for a split-second before being erased, the method below is my solution. Note the numerous additional conditions, this is to avoid disabling all sorts of navigation and hotkeys. If anyone knows how to compactify this, let us know!

<input type="text" 
onkeydown="return ( event.ctrlKey || event.altKey 
                    || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) 
                    || (95<event.keyCode && event.keyCode<106)
                    || (event.keyCode==8) || (event.keyCode==9) 
                    || (event.keyCode>34 && event.keyCode<40) 
                    || (event.keyCode==46) )">

Solution 4:

And one more example, which works great for me:

function validateNumber(event) {
    var key = window.event ? event.keyCode : event.which;
    if (event.keyCode === 8 || event.keyCode === 46) {
        return true;
    } else if ( key < 48 || key > 57 ) {
        return false;
    } else {
        return true;
    }
};

Also attach to keypress event

$(document).ready(function(){
    $('[id^=edit]').keypress(validateNumber);
});

And HTML:

<input type="input" id="edit1" value="0" size="5" maxlength="5" />

Here is a jsFiddle example

Solution 5:

Here is a simple one which allows for exactly one decimal, but no more:

<input type="text" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" />

Solution 6:

HTML5 has <input type=number>, which sounds right for you. Currently, only Opera supports it natively, but there is a project that has a JavaScript implementation.