HTML text input allow only numeric input

  1. Home
  2. javascript
  3. HTML text input allow only numeric input

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

First answer

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

JavaScript

The setInputFilter function below allows you to use any kind of input filter on a text <input>, including various numeric filters (see below).

Unlike most other solutions, this correctly supports Copy+Paste, Drag+Drop, all keyboard shortcuts, all context menu operations, all non-typeable keys (e.g. cursor and navigation keys), the caret position, all keyboard layouts of all languages and platforms, and all browsers since IE 9.

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);
      }
    });
  });
}

// 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 (positive only):
    /^\d*$/.test(value)
  • Integer values (positive and up to a particular limit):
    /^\d*$/.test(value) && (value === "" || parseInt(value) <= 500)
  • Integer values (both positive and negative):
    /^-?\d*$/.test(value)
  • 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)
  • A-Z only (i.e. basic Latin letters):
    /^[a-z]*$/i.test(value)
  • Latin letters only (i.e. English and most European languages, see https://unicode-table.com for details about Unicode character ranges):
    /^[a-z\u00c0-\u024f]*$/i.test(value)
  • Hexadecimal values:
    /^[0-9a-f]*$/i.test(value)

Note that you still must do server side validation!

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.

Second answer

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();
  }
}

Third answer

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) )">
Reprint:https://stackoverflow.com/questions/469357/html-text-input-allow-only-numeric-input
Spread the love

Related articles

Comments are closed.