1127

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

16
  • 105
    Many solutions here only work when keys are pressed. These will fail if people paste text using the menu, or if they drag and drop text into the text input. I've been bitten by that before. Be careful! Commented Jan 24, 2011 at 21:09
  • 1
    @haemse - Not if you use the mouse to paste. Commented Sep 30, 2011 at 21:33
  • 105
    @JuliusA - you always always need server-side validation anyway. Commented Nov 23, 2011 at 1:57
  • 74
    <input type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57'></input> Commented Jan 20, 2013 at 20:13
  • 20
    @Droogans notice that also disables any other key, like TAB to go to the next input or any other shortcut not directly involved with input like cmd+R for refreshing the website if the input is focused. Commented Nov 5, 2013 at 9:54

79 Answers 79

1362

JavaScript

Update: easier solution seems to use beforeinput event.

You can filter the input values of a text <input> with the following setInputFilter function (supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, validity error message, and all browsers since IE 9):

// Restricts input for the given textbox to the given inputFilter function.
function setInputFilter(textbox, inputFilter, errMsg) {
  [ "input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) {
    textbox.addEventListener(event, function(e) {
      if (inputFilter(this.value)) {
        // Accepted value.
        if ([ "keydown", "mousedown", "focusout" ].indexOf(e.type) >= 0){
          this.classList.remove("input-error");
          this.setCustomValidity("");
        }

        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      }
      else if (this.hasOwnProperty("oldValue")) {
        // Rejected value: restore the previous one.
        this.classList.add("input-error");
        this.setCustomValidity(errMsg);
        this.reportValidity();
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      }
      else {
        // Rejected value: nothing to restore.
        this.value = "";
      }
    });
  });
}

You can now use the setInputFilter function to install an input filter:

setInputFilter(document.getElementById("myTextBox"), function(value) {
  return /^\d*\.?\d*$/.test(value); // Allow digits and '.' only, using a RegExp.
}, "Only digits and '.' are allowed");

Apply your preferred style to the input-error class. Here’s a suggestion:

.input-error{
  outline: 1px solid red;
}

Note that you still must do server side validation!

Another caveat is that this will break the undo stack since it sets this.value directly. This means that CtrlZ will not work to undo inputs after typing an invalid character.

Demo

See the JSFiddle demo for more input filter examples or run the Stack snippet below:

// Restricts input for the given textbox to the given inputFilter.
function setInputFilter(textbox, inputFilter, errMsg) {
  [ "input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) {
    textbox.addEventListener(event, function(e) {
      if (inputFilter(this.value)) {
        // Accepted value.
        if ([ "keydown", "mousedown", "focusout" ].indexOf(e.type) >= 0) {
          this.classList.remove("input-error");
          this.setCustomValidity("");
        }
        
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      }
      else if (this.hasOwnProperty("oldValue")) {
        // Rejected value: restore the previous one.
        this.classList.add("input-error");
        this.setCustomValidity(errMsg);
        this.reportValidity();
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      }
      else {
        // Rejected value: nothing to restore.
        this.value = "";
      }
    });
  });
}

// Install input filters.
setInputFilter(document.getElementById("intTextBox"), function(value) {
  return /^-?\d*$/.test(value);
}, "Must be an integer");
setInputFilter(document.getElementById("uintTextBox"), function(value) {
  return /^\d*$/.test(value);
}, "Must be an unsigned integer");
setInputFilter(document.getElementById("intLimitTextBox"), function(value) {
  return /^\d*$/.test(value) && (value === "" || parseInt(value) <= 500);
}, "Must be between 0 and 500");
setInputFilter(document.getElementById("floatTextBox"), function(value) {
  return /^-?\d*[.,]?\d*$/.test(value);
}, "Must be a floating (real) number");
setInputFilter(document.getElementById("currencyTextBox"), function(value) {
  return /^-?\d*[.,]?\d{0,2}$/.test(value);
}, "Must be a currency value");
setInputFilter(document.getElementById("latinTextBox"), function(value) {
  return /^[a-z]*$/i.test(value);
}, "Must use alphabetic latin characters");
setInputFilter(document.getElementById("hexTextBox"), function(value) {
  return /^[0-9a-f]*$/i.test(value);
}, "Must use hexadecimal characters");
.input-error {
  outline: 1px solid red;
}
<h2>JavaScript input filter showcase</h2>
<p>Supports Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, the caret position, different keyboard layouts, and <a href="https://caniuse.com/#feat=input-event" target="_blank">all browsers since IE 9</a>.</p>
<p>There is also a <a href="https://jsfiddle.net/emkey08/tvx5e7q3" target="_blank">jQuery version</a> of this.</p>
<table>
  <tr>
    <td>Integer</td>
    <td><input id="intTextBox"></td>
  </tr>
  <tr>
    <td>Integer &gt;= 0</td>
    <td><input id="uintTextBox"></td>
  </tr>
  <tr>
    <td>Integer &gt;= 0 and &lt;= 500</td>
    <td><input id="intLimitTextBox"></td>
  </tr>
  <tr>
    <td>Float (use . or , as decimal separator)</td>
    <td><input id="floatTextBox"></td>
  </tr>
  <tr>
    <td>Currency (at most two decimal places)</td>
    <td><input id="currencyTextBox"></td>
  </tr>
  <tr>
    <td>A-Z only</td>
    <td><input id="latinTextBox"></td>
  </tr>
  <tr>
    <td>Hexadecimal</td>
    <td><input id="hexTextBox"></td>
  </tr>
</table>

TypeScript

Here is a TypeScript version of this.

function setInputFilter(textbox: Element, inputFilter: (value: string) => boolean, errMsg: string): void {
  ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop", "focusout" ].forEach(function(event) {
    textbox.addEventListener(event, function(this: (HTMLInputElement | HTMLTextAreaElement) & { oldValue: string; oldSelectionStart: number | null, oldSelectionEnd: number | null }) {
      if (inputFilter(this.value)) {
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      }
      else if (Object.prototype.hasOwnProperty.call(this, "oldValue")) {
        this.value = this.oldValue;
        
        if (this.oldSelectionStart !== null &&
          this.oldSelectionEnd !== null) {
          this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
        }
      }
      else {
        this.value = "";
      }
    });
  });
}

jQuery

There is also a jQuery version of this. See this answer.

HTML5

HTML5 has a native solution with <input type="number"> (see the specification and documentation). The documentation has a working demo of this input type.

  • Instead of reading the value property, read the valueAsNumber property of the input to get the typed value as a number rather than a string.
  • Usage inside a <form> is recommended because validation is made easier this way; for example, pressing Enter will automatically show an error message if the value is invalid.
    • You can use the checkValidity method or the requestSubmit method on the entire form in order to explicitly check the validity.
    • Note that you might need to use the required attribute in order to disallow an empty input.
  • You can use the checkValidity method or the validity property on the input element itself in order to explicitly check the validity.
  • You can use reportValidity to show an error message and use setCustomValidity to set your own message.

This approach fundamentally has a different user experience: you are allowed to input invalid characters and the validation is performed separately. This has the benefit that the undo stack (CtrlZ) won’t break. Note that server-side validation must be performed, regardless, no matter which approach you choose.

But note that browser support varies:

Demo

document.querySelector("form").addEventListener("submit", (event) => {
  event.preventDefault();
  console.log(`Submit!
  Number is ${event.target.elements.number.valueAsNumber},
  integer is ${event.target.elements.integer.valueAsNumber},
  form data is ${JSON.stringify(Object.fromEntries(new FormData(event.target).entries()))}.`);
})
label {
  display: block;
}
<form>
  <fieldset>
    <legend>Get a feel for the UX here:</legend>
    <label>Enter any number: <input name="number" type="number" step="any" required></label>
    <label>Enter any integer: <input name="integer" type="number" step="1" required></label>
    <label>Submit: <input name="submitter" type="submit"></label>
  </fieldset>
</form>

Sign up to request clarification or add additional context in comments.

13 Comments

Still not supported by Firefox 21 (I don't even talk about IE9 or earlier version ...)
The type="number" does not actually prevent entering invalid text into the field; appears that you can even cut and paste garbage data into the field, even in chrome.
With thanks to all, I wrote another with min and max range. You could see in: stackoverflow.com/questions/2013229/…
This also allow enter "e" value, I supposed for number with scientific notation 10e3
why input event alone is not enough?
|
330

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

18 Comments

german-settings on an eeepc 900. some key's for good usabiliy do not work: - backspace (keyCode: 8) - navigation key left and right (keyCode: 37, 38) copy and paste is also possible...
few problems with this code. You can enter . more than one time, second it does not allow delete key, any solution?
I cared about backspace, delete and arrows not working. If you remove "theEvent.keycode ||", and add: "if( /[ -~]/ && !regex.test(key) ) {" then it does work better (for ASCII/UTF anyway). But then it won't reject chinese characters! :)
Related too "How to check if a variable is an integer in Javascript?" stackoverflow.com/questions/14636536/…
@Sam i just did this at the start prior to the regex: if (evt.key == "Backspace" || evt.key == "Del") return true;
|
286

Here is a simple one which allows for exactly one decimal, but no more. The input event uses regex to replace text on the fly based on the two patterns:

  1. Remove anything that's not a digit or a dot
  2. Remove any second instance of a dot

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

As someone commented below, the solution above does not handle leading zeros. If your particular use case requires that these are not allowed you can add to the pattern above like so:

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

That will allow 0.123 or .123 but not 0123 or 00.123.

20 Comments

Handles: copy+paste, drag 'n drop, only allows 1 decimal, tab, delete, backspace - use this one
This is the best solution. I upvoted it years ago, but every time I've searched for a solution to this problem, I know that this answer is out there somewhere and I come back to it every time. I don't know what sort of magic OP is channeling, but even if I remove the event via inspector, the rule still applies to the input.
@Hyetigran - I didn't really intend for this to handle leading zeros but I can definitely see where that would be useful. I've added a modified version to my answer to deal with that. Thanks!
@FiddlingAway - what if you have "123.45" and you move the cursor to insert a dot like "1.23.45"? Which dot should it keep? My approach is to simply wipe everything after the newly typed dot. There are certainly other approaches, but since the input is nonsense, this seems reasonable to me.
Nice one! Anyone trying this on react could do something like onInput={(e) => (e.currentTarget.value = e.currentTarget.value .replace(/[^0-9.]/g, "") .replace(/(\..*?)\..*/g, "$1").replace(/^0[^.]/, "0"))}
|
175

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) )">

13 Comments

input type="number" is coming in HTML 5 - and you could use JavaScript as a fall-back polyfill... stevefenton.co.uk/Content/Blog/Date/201105/Blog/…
Good method but can be broken by pressing and holding a non-acceptable key
Change the regex to /[^\d+]/ and it works with holding down
@boecko thanks for this, but note that it should be /[^\d]+/ instead. Good solution though. Also @user235859
He wanted to allow . too. You should actually make it /[^0-9.]/g
|
68

Most answers here all have the weakness of using key- events.

Many of the answers would limit your ability to do text selection with keyboard macros, copy+paste and more unwanted behavior, others seem to depend on specific jQuery plugins, which is killing flies with machineguns.

This simple solution seems to work best for me cross platform, regardless of input mechanism (keystroke, copy+paste, rightclick copy+paste, speech-to-text etc.). All text selection keyboard macros would still work, and it would even limit ones ability to set a non-numeric value by script.

function forceNumeric(){
    var $input = $(this);
    $input.val($input.val().replace(/[^\d]+/g,''));
}
$('body').on('propertychange input', 'input[type="number"]', forceNumeric);

16 Comments

jQuery 1.7+ needed. This is a more complete answer since it takes in account inputs via "copy". And it is also simpler!
An alternative regex: replace(/[^\d]+/g,'') Replace all non-digits with empty string. The "i" (case insensitive) modifier is not needed.
@Atirag If you want decimals you can change the regex /[^\d,.]+/
I think this is best answer here .. +1
why not $('input[type=text]').on('input', forceNumeric);?
|
60

HTML5 supports regexes, so you could use this:

<input id="numbersOnly" pattern="[0-9.]+" type="text">

Warning: Some browsers don't support this yet.

7 Comments

HTML5 also has <input type=number>.
True. You should make this an answer. Ooops, @Ms2ger already has.
The <input type=number> adds arrows for increasing and decreasing in certain browsers so this seems like a good solution when we want to avoid the spinner
Pattern only gets checked on submit. You can still enter letters.
What does the + means in pattern attribute?
|
60

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

12 Comments

Why do I get "event is undefined" when I call this function?
Are you calling validateNumber function on jQuery keypress?
this doesn't work on Firefox when the event.keyCode is always returned 0. I fixed with new code: function validateNumber(event) { var key = event.which || event.charCode || event.keyCode || 0; if (key == 8 || key == 46 || key == 37 || key == 39) { return true; } else if ( key < 48 || key > 57 ) { return false; } return true; };
As @Jessica said, you cam add apostrophe and even percentage sign.
Very close! but does allow more than one decimal.
|
59

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.

5 Comments

Here's a document defining which browsers support this attribute: caniuse.com/input-number. As of the writing of this, Chrome and Safari both fully support this type field. IE 10 has partial support, and Firefox has no support.
The only problem with type=number is that is not supported by IE9
@JRod There's a polyfill for old IE. More info here.
First problem is type=number is allowing the e char because it consider e+10 as number. Second problem is that you can not limit the maximum number of chars in the input.
Another problem is that if the type is number then I can't get the benefits of setting the type to, for example: "tel".
44

I opted to use a combination of the two answers mentioned here i.e.

<input type="number" />

and

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode
    return !(charCode > 31 && (charCode < 48 || charCode > 57));
}

<input type="text" onkeypress="return isNumberKey(event);">

2 Comments

How about deleting though? You want numbers but you probably want people to be able to correct them without refreshing the page...
@MartinErlic I've tried, deleting is normally working. I think this is the best answer.
22

JavaScript

function validateNumber(evt) {
    var e = evt || window.event;
    var key = e.keyCode || e.which;

    if (!e.shiftKey && !e.altKey && !e.ctrlKey &&
    // numbers   
    key >= 48 && key <= 57 ||
    // Numeric keypad
    key >= 96 && key <= 105 ||
    // Backspace and Tab and Enter
    key == 8 || key == 9 || key == 13 ||
    // Home and End
    key == 35 || key == 36 ||
    // left and right arrows
    key == 37 || key == 39 ||
    // Del and Ins
    key == 46 || key == 45) {
        // input is VALID
    }
    else {
        // input is INVALID
        e.returnValue = false;
        if (e.preventDefault) e.preventDefault();
    }
}

additional you could add comma, period and minus (,.-)

  // comma, period and minus, . on keypad
  key == 190 || key == 188 || key == 109 || key == 110 ||

HTML

<input type="text" onkeydown="validateNumber(event);"/ >

3 Comments

Does not function correctly on keyboards where one has to use the shift key to enter a number (e.g. European AZERTY keyboard).
This is the only one that works that prevent pasting non numeric values.
Does not allow paste with any method whatsoever.
17

2 solutions:

Use a form validator (for example with jQuery validation plugin)

Do a check during the onblur (i.e. when the user leaves the field) event of the input field, with the regular expression:

<script type="text/javascript">
function testField(field) {
    var regExpr = new RegExp("^\d*\.?\d*$");
    if (!regExpr.test(field.value)) {
      // Case of error
      field.value = "";
    }
}

</script>

<input type="text" ... onblur="testField(this);"/>

4 Comments

Interestingly, I had to give the regex is "^\\d\\.?\\d*$", but that might be because the page is run through an XSLT transform.
I think the regular expression is incorrect. I used this line: var regExpr = /^\d+(\.\d*)?$/;
@costa not sure, if the user wants to input .123 (instead of 0.123) for example?
@romaintaz. You are right, but then you'd have to change the regular expression to make sure that in case there is no digit in front of the dot there are digits after the dot. Something like this: var regExpr = /^\d+(\.\d*)?$|^\.\d+$/;.
16

One more example where you can add only numbers in the input field, can not letters

<input type="text" class="form-control" id="phone" name="phone" placeholder="PHONE" spellcheck="false" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');">

Comments

16

// In a JavaScript function (can use HTML or PHP).

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

In your form input:

<input type=text name=form_number size=20 maxlength=12 onkeypress='return isNumberKey(event)'>

With input max. (These above allows for a 12-digit number)

2 Comments

Don't do that ! This blocks everything, numpad, arrow keys, Delete key, shortcuts (CTRL + A, CTRL + R for example), even the TAB key it's REALY anoying !
@Korri I dont follow, what seems to be the problme? It did work fine in my case.
15

You can use pattern for this:

<input id="numbers" pattern="[0-9.]+" type="number">

Here you can see the complete mobile website interface tips.

3 Comments

Wont work in IE8 and 9. See caniuse. Still a good answer.
You can also add a title="numbers only" to display the error
<input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. developer.mozilla.org/en-US/docs/Web/HTML/Element/input/…
15

A safer approach is checking the value of the input, instead of hijacking keypresses and trying to filter keyCodes.

This way the user is free to use keyboard arrows, modifier keys, backspace, delete, use non standard keyboards, use mouse to paste, use drag and drop text, even use accessibility inputs.

The below script allows positive and negative numbers

1
10
100.0
100.01
-1
-1.0
-10.00
1.0.0 //not allowed

var input = document.getElementById('number');
input.onkeyup = input.onchange = enforceFloat;

//enforce that only a float can be inputed
function enforceFloat() {
  var valid = /^\-?\d+\.\d*$|^\-?[\d]*$/;
  var number = /\-\d+\.\d*|\-[\d]*|[\d]+\.[\d]*|[\d]+/;
  if (!valid.test(this.value)) {
    var n = this.value.match(number);
    this.value = n ? n[0] : '';
  }
}
<input id="number" value="-3.1415" placeholder="Type a number" autofocus>

EDIT: I removed my old answer because I think it is antiquated now.

2 Comments

This indeed seems to cover most cases
If you dislike the non-accepted character showing for a split-second before being erased, use beforeinput event stackoverflow.com/questions/70806083/…
13

Please find below mentioned solution. In this user can be able to enter only numeric value, Also user can not be able to copy, paste, drag and drop in input.

Allowed Characters

0,1,2,3,4,5,6,7,8,9

Not allowed Characters and Characters through events

  • Alphabetic value
  • Special characters
  • Copy
  • Paste
  • Drag
  • Drop

$(document).ready(function() {
  $('#number').bind("cut copy paste drag drop", function(e) {
      e.preventDefault();
  });     
});
function isNumberKey(evt) {
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" class="form-control" name="number" id="number" onkeypress="return isNumberKey(event)" placeholder="Enter Numeric value only">

Let me know if it not works.

1 Comment

This allows key "e" and decimal confirmed in chrome.
12

If you want to suggest to the device (maybe a mobile phone) between alpha or numeric you can use

<input type="number">

Comments

11

A short and sweet implementation using jQuery and replace() instead of looking at event.keyCode or event.which:

$('input.numeric').live('keyup', function(e) {
  $(this).val($(this).val().replace(/[^0-9]/g, ''));
});

Only small side effect that the typed letter appears momentarily and CTRL/CMD + A seems to behave a bit strange.

Comments

10

JavaScript code:

function validate(evt)
{
    if(evt.keyCode!=8)
    {
        var theEvent = evt || window.event;
        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();
            }
        }
    }

HTML code:

<input type='text' name='price' value='0' onkeypress='validate(event)'/>

works perfectly because the backspace keycode is 8 and a regex expression doesn't let it, so it's an easy way to bypass the bug :)

Comments

10

just use type="number" now this attribute supporting in most of the browsers

<input type="number" maxlength="3" ng-bind="first">

1 Comment

I haven't check data is --1 (2 minus characters before 1).
10

A easy way to resolve this problem is implementing a jQuery function to validate with regex the charaters typed in the textbox for example:

Your html code:

<input class="integerInput" type="text">

And the js function using jQuery

$(function() {
    $('.integerInput').on('input', function() {
      this.value = this.value
        .replace(/[^\d]/g, '');// numbers and decimals only

    });
});

$(function() {
        $('.integerInput').on('input', function() {
          this.value = this.value
            .replace(/[^\d]/g, '');// numbers and decimals only
            
        });
    });
<script
			  src="https://code.jquery.com/jquery-2.2.4.min.js"
			  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
			  crossorigin="anonymous">
</script>

<input type="text" class="integerInput"/>


		

Comments

9

input type="number" is an HTML5 attribute.

In the other case this will help you:

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : evt.keyCode
    if (charCode > 31 && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

<input type="number" name="somecode" onkeypress="return isNumberKey(event)"/>

Comments

8

Just an other variant with jQuery using

$(".numeric").keypress(function() {
    return (/\d/.test(String.fromCharCode(event.which) ))
});

Comments

8

I saw some great answers however I like them as small and as simple as possible, so maybe someone will benefit from it. I would use javascript Number() and isNaN functionality like this:

if(isNaN(Number(str))) {
   // ... Exception it is NOT a number
} else {
   // ... Do something you have a number
}

Hope this helps.

4 Comments

I love this! Such an elegant solution, no regex involved.
This is not an answer to the question, OP asked to only allow text on a input, not verify afterwards.
Yes, that is truth! But there is already an accepted answer which I think is good, but I thought this might help somebody, plus it's nice and clean.
Keep in mind that Number("") produces 0. If you want NaN in case of empty inputs, use either parseFloat(str) or add a check for empty string.
7
<input name="amount" type="text" value="Only number in here"/> 

<script>
    $('input[name=amount]').keyup(function(){
        $(this).val($(this).val().replace(/[^\d]/,''));
    });
</script>

Comments

6

You can also compare input value (which is treated as string by default) to itself forced as numeric, like:

if(event.target.value == event.target.value * 1) {
    // returns true if input value is numeric string
}

However, you need to bind that to event like keyup etc.

Comments

5

My solution for a better user experience:

HTML

<input type="tel">

jQuery

$('[type=tel]').on('change', function(e) {
  $(e.target).val($(e.target).val().replace(/[^\d\.]/g, ''))
})
$('[type=tel]').on('keypress', function(e) {
  keys = ['0','1','2','3','4','5','6','7','8','9','.']
  return keys.indexOf(event.key) > -1
})

Details:

First of all, input types:

number shows up/down arrows shrinking the actual input space, I find them ugly and are only useful if the number represents a quantity (things like phones, area codes, IDs... don't need them) tel provides similar browser validations of number without arrows

Using [number / tel] also helps showing numeric keyboard on mobile devices.

For the JS validation I ended up needing 2 functions, one for the normal user input (keypress) and the other for a copy+paste fix (change), other combinations would give me a terrible user experience.

I use the more reliable KeyboardEvent.key instead of the now deprecated KeyboardEvent.charCode

And depending of your browser support you can consider using Array.prototype.includes() instead of the poorly named Array.prototype.indexOf() (for true / false results)

Comments

5

Use this DOM:

<input type = "text" onkeydown = "validate(event)"/>

And this script:

validate = function(evt)
{
    if ([8, 46, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, 36].indexOf(evt.keyCode || evt.which) == -1)
    {
        evt.returnValue = false;
        if(evt.preventDefault){evt.preventDefault();}
    }
}

...OR this script, without indexOf, using two for's...

validate = function(evt)
{
    var CharValidate = new Array("08", "046", "039", "948", "235");
    var number_pressed = false;
    for (i = 0; i < 5; i++)
    {
        for (Ncount = 0; Ncount < parseInt(CharValidate[i].substring(0, 1)) + 1; Ncount++)
        {
            if ((evt.keyCode || evt.which) == parseInt(CharValidate[i].substring(1, CharValidate[i].lenght)) + Ncount)
            {
                number_pressed = true;
            }
        }
    }
    if (number_pressed == false)
    {
        evt.returnValue = false;
        if(evt.preventDefault){evt.preventDefault();}
    }
}

I used the onkeydown attribute instead of onkeypress, because the onkeydown attribute is checked before onkeypress attribute. The problem would be in the Google Chrome browser.

With the attribute "onkeypress", TAB would be uncontrollable with "preventDefault" on google chrome, however, with the attribute "onkeydown", TAB becomes controllable!

ASCII Code for TAB => 9

The first script have less code than the second, however, the array of ASCII characters must have all the keys.

The second script is much bigger than the first, but the array does not need all keys. The first digit in each position of the array is the number of times each position will be read. For each reading, will be incremented 1 to the next one. For example:




NCount = 0

48 + NCount = 48

NCount + +

48 + NCount = 49

NCount + +

...

48 + NCount = 57




In the case of numerical keys are only 10 (0 - 9), but if they were 1 million it would not make sense to create an array with all these keys.

ASCII codes:

  • 8 ==> (Backspace);
  • 46 => (Delete);
  • 37 => (left arrow);
  • 39 => (right arrow);
  • 48 - 57 => (numbers);
  • 36 => (home);
  • 35 => (end);

Comments

5

This is an improved function:

function validateNumber(evt) {
  var theEvent = evt || window.event;
  var key = theEvent.keyCode || theEvent.which;
  if ((key < 48 || key > 57) && !(key == 8 || key == 9 || key == 13 || key == 37 || key == 39 || key == 46) ){
    theEvent.returnValue = false;
    if (theEvent.preventDefault) theEvent.preventDefault();
  }
}

Comments

5

Here is my simple solution for React users only, I couldn't find a better solution and made my own. 3 steps.

First, create a state.

const [tagInputVal, setTagInputVal] = useState("");

Then, use the state as input value (value={tagInputVal}) and pass the event to the onChange handler.

<input id="tag-input" type="text" placeholder="Add a tag" value={tagInputVal} onChange={(e) => onChangeTagInput(e)}></input>

Then, set the value of the event inside onChange handler.

function onChangeTagInput(e) {
    setTagInputVal(e.target.value.replace(/[^\d.]/ig, ""));
}

2 Comments

This or any javascript solution has this advantage over <input type="number"> that sometimes the input value is not a number in terms of semantics (It can't be incremented), rather it's a numerical code like one-time passwords.
The problem with this approach though is that when you set the type to "text" instead of "number", you lose the number stepper.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.