1101

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

emkey08
  • 5,059
  • 3
  • 33
  • 34
Julius A
  • 38,062
  • 26
  • 74
  • 96
  • 101
    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! – Bennett McElwee Jan 24 '11 at 21:09
  • if you do the validation on keyup event, pasting of the user will be validated because auf de keyup of the "v" - key ... – haemse Apr 14 '11 at 09:06
  • 1
    @haemse - Not if you use the mouse to paste. – VirtuosiMedia Sep 30 '11 at 21:33
  • I suppose in that case, you will need server-side validation to complement the client javascript – Julius A Oct 03 '11 at 11:16
  • 103
    @JuliusA - you *always* ***always*** need server-side validation anyway. – Stephen P Nov 23 '11 at 01:57
  • 73
  • 19
    @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. – Alejandro Pérez Nov 05 '13 at 09:54
  • There is a lot of "html5 will save us" in this thread. Spoiler alert, it doesn't. – blu Mar 26 '14 at 15:07
  • 1
    If you are okay with Plugin, use NumericInput. Demo: http://jsfiddle.net/152sumxu/2/ More details here http://stackoverflow.com/a/27561763/82961 – Faiz Dec 19 '14 at 07:53
  • I cannot satisfy with those, so I wrote my own here https://github.com/lockevn/html-numeric-input. This will let numeric, dot, minus sign come in, but it will post-validate the value on keyup to ensure the correct number value, even if you paste a wrong value into the textbox. – Thach Lockevn Nov 04 '15 at 03:00
  • 1
    `onkeyup="this.value = this.value.replace(/[^0-9]/g, '');" `. No HTML5 (http://caniuse.com/#search=type%3D%22number%22), No Jquery (http://stackoverflow.com/a/5123892/533510 or http://stackoverflow.com/a/5100002/533510). Good luck for those mapping edition keys, if tomorrow Browsers/OSs add more editing capabilities (imaginary example: like control+* for reverting the character order). – ribamar Dec 29 '15 at 16:48
  • (Disclaimer: works only for integers, extend the regex for your case) – ribamar Dec 29 '15 at 16:55
  • 1
    one could use onchange event and check the textbox value as `isNaN()` – Madeyedexter Jun 28 '16 at 08:05
  • @BennettMcElwee I struggled with it and came up with this [solution](http://stackoverflow.com/a/43221717/250848) that includes the copy+paste fix – mencargo Apr 05 '17 at 04:26
  • Quick & dirty: `` – William Entriken Mar 04 '20 at 17:19

79 Answers79

1354

JavaScript

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>
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Ian G
  • 29,468
  • 21
  • 78
  • 92
  • 7
    Still not supported by Firefox 21 (I don't even talk about IE9 or earlier version ...) – JBE May 24 '13 at 17:40
  • 12
    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. – perfectionist Jun 13 '14 at 11:15
  • With thanks to all, I wrote another with min and max range. You could see in: http://stackoverflow.com/questions/2013229/jquery-numeric-textbox-with-min-and-max-ranges/25710687#25710687 – QMaster Sep 07 '14 at 13:34
  • 1
    This also allow enter "e" value, I supposed for number with scientific notation 10e3 – Diego Quirós Nov 04 '15 at 01:05
  • if you want input in float – Shahzain ali Aug 15 '17 at 06:30
  • 2018/10/12, set my inpyt as type='number' or 'tel', but alphanumeric still available for input, tested under newest Chrome and Firefox...... – RRTW Oct 12 '18 at 07:27
  • Chrome plugin "Form Filler" will break this script and will allow just anything to be entered after initial use. – vzr Sep 19 '19 at 13:12
  • This answer is the correct, but, do not put type to the input, it gets unstable (I can't tell why), the input should be without type – Andres Felipe Jun 06 '21 at 14:42
  • Ellegant and efficient way to add such filters, comments saying this does not work, due to adding multiple dots, copy pasting, etc.... are invalid (on chrome at least) it is not possible to add multiple dots or copy paste inside the box with these filters – S.. Jun 14 '21 at 15:57
  • use the regex ^\d*(\.|,)?\d*$ if you need additional comma support. – nonNumericalFloat Jul 15 '21 at 18:15
  • 1
    why `input` event alone is not enough? – Alex78191 Oct 21 '21 at 06:28
  • "INPUT TYPE=Number..." in Chrome adds arrows (by default) and increases the width of the text-box. You may not want this side-effect. (It's a bad choice on Chrome's behalf in my opinion. Make the width change and arrows optional and not the default behavior. It breaks convention, and is often confusing.) – FloverOwe Dec 29 '21 at 01:37
  • DO NOT SET THE input.type to 'text' (at least in firefox it filters the values it passes to your func and messes it up – Ali May 12 '22 at 21:22
326

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();
  }
}
SuperStormer
  • 4,997
  • 5
  • 25
  • 35
geowa4
  • 40,390
  • 17
  • 88
  • 107
  • 12
    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... – Michael Piendl Sep 10 '09 at 18:24
  • 14
    few problems with this code. You can enter . more than one time, second it does not allow delete key, any solution? – coure2011 May 16 '11 at 11:09
  • 4
    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! :) – Sam Watkins Jun 03 '11 at 07:44
  • this is old school now, html 5 spinner widget rocks! – jsDebugger Apr 23 '13 at 03:58
  • This solution works fine in Firefox but still allows some characters (&é"'(-è_çà) under Chrome or IE depending on the local. I had to combine it with an onKeyUp check to rollback the last char in case it was not a number. – JBE May 24 '13 at 17:34
  • Related: `"Is there a (built-in) way in JavaScript to check if a string is a valid number?"` http://stackoverflow.com/questions/175739/is-there-a-built-in-way-in-javascript-to-check-if-a-string-is-a-valid-number – Adriano Jun 26 '14 at 12:30
  • 1
    Related too `"How to check if a variable is an integer in Javascript?"` http://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript – Adriano Jun 26 '14 at 12:34
  • Live example on how to use the 2 technics above together http://jsfiddle.net/787j3/ – Adriano Jun 26 '14 at 13:01
  • Live example on how to leverage the 2 technics on click button http://jsfiddle.net/85fbP/ – Adriano Jun 26 '14 at 13:15
  • Live example on how to leverage the 2 technics on input type text keyup http://jsfiddle.net/s58LX/ – Adriano Jun 26 '14 at 13:18
  • 3
    @Sam i just did this at the start prior to the regex: if (evt.key == "Backspace" || evt.key == "Del") return true; – Chris Jul 18 '14 at 16:53
  • Isn't using attributes with javascript deprecated? – Gherman Aug 28 '14 at 10:31
  • @Chris and how about arrows ? and disable the dot ? That would be great. – Francisco Corrales Morales Oct 08 '14 at 22:29
  • @FranciscoCorralesMorales you can disable any keys you like, to determine what evt.key value will be just set a breakpoint in your method and press the key that you want to test. Any browser dev tools will do (firebug, IE dev tools, visual studio, etc etc) – Chris Oct 10 '14 at 13:44
  • var theEvent = evt || $window.event, key = theEvent.keyCode || theEvent.which, BACKSPACE = 8, DEL = 46, ARROW_KEYS = {left: 37, right: 39}, regex = /[0-9]|\./; if (key === BACKSPACE || key === DEL || key === ARROW_KEYS.left || key === ARROW_KEYS.right) { return true; } ... the rest of the script – Santiago Rebella Dec 19 '14 at 19:54
  • **JUST A TIP:** do yourself a favor and change it to `keydown` --- save yourself a **`keyup` event** (also related, if you are looking into `input`/`textarea` content, use the on keyup, saves you **a ton of an unneeded events** and **slow dom**, **if user is holding a key-down**) –  Dec 09 '15 at 01:16
  • This is very good, the only issue I see with this is when someone pastes into the input field, to prevent this from happening I'd use the "oninput" event rather than "onkeypress" (e.g. ) – Beavatron Prime Mar 27 '19 at 08:56
  • For no decimal point, just update to : `var regex = /[0-9]/;` – rgy Sep 01 '20 at 09:29
250

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.

  • 33
    Handles: copy+paste, drag 'n drop, only allows 1 decimal, tab, delete, backspace - use this one – Mathemats Jan 16 '18 at 03:36
  • Can this logic inside oninput be extracted so that can be used globally? – ema Jan 29 '19 at 12:34
  • @ema - yes, see my other answer [here](https://stackoverflow.com/a/32320458/1767412) which shows how you can apply the rule using class. – But those new buttons though.. Jan 29 '19 at 14:33
  • if you use this on angular form the value wont update in form control value. – Alessandro_Russo Jul 16 '19 at 15:39
  • Awesome. I change the event to this.value = this.value.replace(/[^0-9.-]/g, '').replace(/(\..*)\./g, '$1').replace(/^0+/g, '').replace(/(?<!^)-/g, ''); This way it handles only a - at the beginning and doesn't allow 0's at the beginning of the number. – brenth Jul 17 '19 at 15:41
  • this.value.replace(/[^0-9.]/g, '') replace . from this regex if you don't want to use decimal; value...its wonderful solution – iamawesome Sep 12 '19 at 11:28
  • 4
    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. – Ethan Moore Jun 09 '21 at 17:15
  • Great solution! I have tried to apply it to my imput generated dynamically by js but '\' marks are not transfered to my html and this solution works just partially. My try looks like this: `input.setAttribute('oninput',"this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');")` Anybody knows how to solve this problem? – user13137381 Mar 24 '22 at 19:41
  • @user13137381 - use a delegated event and a class instead of inline `oninput` event. event example is [here](https://stackoverflow.com/questions/10150877/allowing-input-only-for-float-number/32320458#32320458). If you have a dynamic page you'll need to change the syntax to a delegated event by putting your input selector after `on` https://api.jquery.com/on/ – But those new buttons though.. Mar 24 '22 at 20:31
  • I'm late to the party, but wanted to add that this does not handle for leading zeros – Hyetigran Apr 07 '22 at 20:17
  • 1
    @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! – But those new buttons though.. Apr 07 '22 at 21:08
  • One tiny bug. Steps to reproduce: 1. type in a number 2. navigate through its digits via arrow keys somewhere in the middle of it 3. press the dot key once 4. press the dot key the second time. End result is that the decimals will be removed. – FiddlingAway Jun 22 '22 at 10:42
  • @FiddlingAway - the input is respecting the rules. What would you expect to happen? – But those new buttons though.. Jun 22 '22 at 11:41
  • @EatenbyaGrue Just for it to delete the new dot, and not trim what's behind it. The expectation was based on this - accidental typing of the second dot, whether in the input itself, or in the pasted / dropped content. That is to say, if 123..45 is typed / pasted / dropped, I'd expect it to be 123.45 in the end. Looking at the regex more closely now, I see why it's working the way it is. – FiddlingAway Jun 23 '22 at 07:41
  • 2
    @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. – But those new buttons though.. Jun 23 '22 at 13:00
  • @EatenbyaGrue Good point. I'd still go with eliminating consecutive dots, but I guess that's just me. – FiddlingAway Jun 23 '22 at 13:26
  • 1
    @FiddlingAway = This could be used to do that: `this.value = this.value.replace(/[^0-9.]/g, '').replace(/\.\.+/g, '.').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');` – But those new buttons though.. Jun 23 '22 at 16:15
  • 1
    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"))}` – Gogol Dec 01 '22 at 20:08
173

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) )">
SuperStormer
  • 4,997
  • 5
  • 25
  • 35
user235859
  • 1,174
  • 1
  • 10
  • 6
  • 5
    input type="number" is coming in HTML 5 - and you could use JavaScript as a fall-back polyfill... http://www.stevefenton.co.uk/Content/Blog/Date/201105/Blog/HTML-5-Forms-Number-Input-Elements/ – Fenton May 23 '11 at 23:06
  • 5
    Good method but can be broken by pressing and holding a non-acceptable key –  Nov 16 '11 at 16:24
  • Yup, this solution doesn't work when holding down a non-number key. – jinsungy Feb 03 '12 at 04:18
  • 8
    Change the regex to `/[^\d+]/` and it works with holding down – boecko Apr 24 '12 at 17:01
  • 12
    @boecko thanks for this, but note that it should be `/[^\d]+/` instead. Good solution though. Also @user235859 – Mosselman Jun 11 '12 at 21:49
  • 11
    He wanted to allow `.` too. You should actually make it `/[^0-9.]/g` – Qsario Aug 01 '12 at 07:20
  • This solution does not take into account the local ! It works for english keyboards only. If you use a french keyboard for example the shiftKey must be true when keycode is between 47 and 58 ... – JBE May 24 '13 at 17:02
  • Second solution is good because it prevents the "key-bashing," but don't forget to include keyCodes 190 and 109 for the decimal point. Using MVC4, you can encapsulate this solution by creating an Html helper method (something like Html.NumericTextBoxFor), and moving the onkeydown logic into a string variable there. – Charlie Oct 17 '13 at 20:01
  • 1
    For the regex you can just do `\D` instead of `[^\d]` or `[^0-9]`. It means "any non-numeric character". – BadHorsie Apr 28 '15 at 17:14
  • 1
    try to paste "abc", DOESN'T WORK. – DEREK LEE Jan 11 '16 at 15:11
  • 3
    @DEREKLEE IT ISN'T SUPPOSED TO – Jessica Jan 04 '17 at 04:21
  • when the user keep pressing down the same letter, the pc will write lets say 10 times this letter, only the last letter will be removed. Also as @DEREKLEE said when u paste a value it won't remove it. – Chris Sim Jan 13 '17 at 10:23
  • @user235859 - Compactified: – Beavatron Prime Mar 27 '19 at 09:11
67

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);
EJTH
  • 2,178
  • 1
  • 20
  • 25
  • jQuery 1.7+ needed. This is a more complete answer since it takes in account inputs via "copy". And it is also simpler! – Memochipan Jun 29 '15 at 15:30
  • An alternative regex: `replace(/[^\d]+/g,'')` Replace all non-digits with empty string. The "i" (case insensitive) modifier is not needed. – Memochipan Jun 29 '15 at 16:20
  • This should be on top, since "onkey" event handlers in a tag should not be propagated any more... – gpinkas Oct 13 '15 at 12:12
  • This one is definitely the best answer here but it doesn't allow digits with decimal numbers. Any idea how that could work? – Atirag Sep 04 '16 at 13:05
  • 8
    @Atirag If you want decimals you can change the regex `/[^\d,.]+/` – EJTH Sep 05 '16 at 09:12
  • This answer is off-topic. The question was how to make a HTML text input allow only numeric. This is about a HTML5 number input. So please be warned that this solution is not backwards compatible. – JPA Jul 30 '17 at 07:51
  • No this is not about HTML5 number input. This answer is about polyfilling said functionality. @JPA – EJTH Aug 16 '17 at 12:45
  • @EJTH - The query `input[type="number"]` can not ever find `input[type="text"]` elements. This is the question here. Ask yourself: Would this polyfill still work (and not interfere with possible other text inputs) if you replaced `input[type="number"]` with `input[type="text"]`? – JPA Feb 25 '18 at 22:22
  • I'm using an older version of asp.net, and this worked for me, by changing: `'input[mtype="number"]'` I then added 'mtype=number' as an attribute to a control. the ASP.net makes each control 'type=text'. – Robert Koernke Mar 22 '18 at 17:13
  • what's the point of defining `$input`? And why use jQuery at all here? I'm a huge fan of jQuery but in this case it complicates the code unnecessarily. – But those new buttons though.. Oct 15 '18 at 01:35
  • Defining $input instead of using $(this) multiple times, in hindsight I should have just used this.value. Its trivial to rewrite this without using jquery. I used to write alot of applications at that time that required stuff to work in browser versions as low as IE8+9, jQuery was the sane choice at the time to ensure onpropertychange support, but the consensus nowadays seems to screw over legacy browsers (Which I think is a good thing). But you should ask, why even use JS at all, since type="number" has wide support these days... – EJTH Oct 15 '18 at 10:03
  • @EJTH: The question, literally was: Is there a quick way to set an HTML **text** input () to only allow numeric keystrokes (plus '.')? By the way, a number input with a non numeric character has its value removed. For the record, the number input is very complex. My advice is to never replace values of/in it. Think about countries that use a decimal comma. – JPA May 12 '19 at 21:53
  • @JPA I agree this answer is not helpful today. It used to be a handy polyfill for browsers that didn't support number input. – EJTH Jul 02 '19 at 14:47
  • I think this is best answer here .. +1 – Mohammad Reza Shahrestani Oct 16 '19 at 07:24
  • *others seem to depend on specific jQuery plugins, which is killing flies with machineguns.* Answerer: uses jQuery for the job. – connexo Apr 27 '21 at 20:08
  • why not `$('input[type=text]').on('input', forceNumeric);`? – Alex78191 Oct 21 '21 at 06:46
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.

Ms2ger
  • 15,596
  • 6
  • 36
  • 35
  • Here's a document defining which browsers support this attribute: http://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. – Nathan Wallace Jul 25 '13 at 14:05
  • The only problem with `type=number` is that is not supported by IE9 – J Rod Jun 06 '16 at 02:32
  • @JRod There's a [polyfill](https://github.com/jonstipe/number-polyfill) for old IE. More info [here](http://stackoverflow.com/a/13955916/3345375). – jkdev Jul 07 '16 at 08:40
  • 14
    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. – Hakan Fıstık Oct 26 '17 at 15:30
  • Another problem is that if the type is number then I can't get the benefits of setting the type to, for example: "tel". – ScottyBlades Feb 15 '20 at 17:07
58

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

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
Vasyl
  • 1,393
  • 15
  • 26
  • Why do I get "event is undefined" when I call this function? – Vincent Mar 06 '14 at 19:25
  • Are you calling validateNumber function on jQuery keypress? – Vasyl Mar 20 '14 at 14:34
  • 3
    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; }; – Luan Nguyen Nov 24 '15 at 22:41
  • It works as expected, event.keyCode returns code of arrow button key if it is pressed – Vasyl Nov 25 '15 at 08:47
  • I would add `9` (tab) and `13` (enter) for the allowed `event.keyCode` list. – totymedli Dec 17 '15 at 11:08
  • @totymedli yes, that make sence – Vasyl Dec 18 '15 at 14:15
  • This allows a single quote `'` – Jessica Jan 26 '16 at 04:34
  • @HVarma, you can add handler $('[id^=edit]').on('paste', function () {...}); But not sure it helps you, because U can't hadle context menu actions in browser – Vasyl Dec 12 '16 at 10:33
  • 1
    As @Jessica said, you cam add apostrophe and even percentage sign. – alejnavab Dec 13 '16 at 20:35
  • Guys, function is updated now, thanks for your comments! Verified on latest Chrome and IE 11 – Vasyl Dec 14 '16 at 12:19
  • 1
    Very close! but does allow more than one decimal. – kross Aug 15 '17 at 22:30
  • Arrow keys don't work :( which then gets you thinking about Home/End, Ctrl+Arrow... – A N Oct 18 '18 at 19:57
58

HTML5 supports regexes, so you could use this:

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

Warning: Some browsers don't support this yet.

james.garriss
  • 12,959
  • 7
  • 83
  • 96
43

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

Mahendra Liya
  • 12,912
  • 14
  • 88
  • 114
  • 7
    How about deleting though? You want numbers but you probably want people to be able to correct them without refreshing the page... – Martin Erlic Feb 03 '16 at 01:27
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);"/ >
patrick
  • 21
  • 1
  • 3
17

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

Osanda Gamage
  • 446
  • 2
  • 6
  • 16
Rizal Aditya
  • 1
  • 1
  • 2
  • 1
    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 Feb 22 '13 at 21:56
  • @Korri I dont follow, what seems to be the problme? It did work fine in my case. – uneakharsh Mar 28 '13 at 12:21
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);"/>
Ian Jacobs
  • 5,456
  • 1
  • 23
  • 38
Romain Linsolas
  • 79,475
  • 49
  • 202
  • 273
  • Interestingly, I had to give the regex is "^\\d\\.?\\d*$", but that might be because the page is run through an XSLT transform. – Paul Tomblin Apr 22 '10 at 15:04
  • I think the regular expression is incorrect. I used this line: `var regExpr = /^\d+(\.\d*)?$/;` – boggy Jan 10 '17 at 23:07
  • @costa not sure, if the user wants to input `.123` (instead of `0.123`) for example? – Romain Linsolas Jan 16 '17 at 08:20
  • @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+$/;`. – boggy Jan 16 '17 at 19:09
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');">
Mile Mijatović
  • 2,948
  • 2
  • 22
  • 41
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ashisha Nautiyal
  • 1,389
  • 2
  • 19
  • 39
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 keyboars, 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.

Vitim.us
  • 20,746
  • 15
  • 92
  • 109
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.

Alex Mac
  • 2,970
  • 1
  • 22
  • 39
12

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

<input type="number">
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
Steven
  • 61
  • 1
  • 2
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.

Tarmo
  • 5,862
  • 2
  • 19
  • 12
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 :)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AirWolf
  • 11
  • 1
  • 2
10

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

<input type="number" maxlength="3" ng-bind="first">
saigopi.me
  • 14,011
  • 2
  • 83
  • 54
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"/>


  
Michiel
  • 4,160
  • 3
  • 30
  • 42
AleKennedy
  • 93
  • 2
  • 7
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)"/>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vaishali Tekale
  • 101
  • 2
  • 2
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.

Sicha
  • 37
  • 1
  • 3
  • 1
    I love this! Such an elegant solution, no regex involved. – Levi Roberts Jun 26 '19 at 02:22
  • This is not an answer to the question, OP asked to only allow text on a input, not verify afterwards. – Timberman Jan 20 '20 at 15:03
  • 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. – Sicha Jan 24 '20 at 09:25
  • 1
    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. – connexo Apr 27 '21 at 20:10
8

Just an other variant with jQuery using

$(".numeric").keypress(function() {
    return (/\d/.test(String.fromCharCode(event.which) ))
});
shanethehat
  • 15,460
  • 11
  • 57
  • 87
Shurok
  • 195
  • 1
  • 9
6
<input name="amount" type="text" value="Only number in here"/> 

<script>
    $('input[name=amount]').keyup(function(){
        $(this).val($(this).val().replace(/[^\d]/,''));
    });
</script>
Voidcode
  • 1,229
  • 1
  • 18
  • 22
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.

cincplug
  • 1,024
  • 5
  • 20
  • 38
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);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Daniel
  • 46
  • 1
  • 3
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)

mencargo
  • 111
  • 4
  • 11
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();
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ehsan Chavoshi
  • 681
  • 6
  • 10
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, ""));
}
Mehedi
  • 281
  • 3
  • 5
  • This or any javascript solution has this advantage over `` 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. – Ehsan88 Sep 12 '21 at 10:07
  • The problem with this approach though is that when you set the type to "text" instead of "number", you lose the number stepper. – dustydojo Nov 08 '22 at 20:28
4

This is the extended version of geowa4's solution. Supports min and max attributes. If the number is out of range, the previous value will be shown.

You can test it here.

Usage: <input type=text class='number' maxlength=3 min=1 max=500>

function number(e) {
var theEvent = e || window.event;
var key = theEvent.keyCode || theEvent.which;
if(key!=13&&key!=9){//allow enter and tab
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key)) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
    }   
  }
}

$(document).ready(function(){
    $("input[type=text]").filter(".number,.NUMBER").on({
        "focus":function(e){
         $(e.target).data('oldValue',$(e.target).val());
            },
        "keypress":function(e){
                e.target.oldvalue = e.target.value;
                number(e);
            },
        "change":function(e){
            var t = e.target;
            var min = $(t).attr("min");
            var max = $(t).attr("max");
            var val = parseInt($(t).val(),10);          
            if( val<min || max<val)
                {
                    alert("Error!");
                    $(t).val($(t).data('oldValue'));
                }

            }       
    });     
});

If the inputs are dynamic use this:

$(document).ready(function(){
    $("body").on("focus","input[type=text].number,.NUMBER",function(e){
        $(e.target).data('oldValue',$(e.target).val());
    }); 
    $("body").on("keypress","input[type=text].number,.NUMBER",function(e){
        e.target.oldvalue = e.target.value;
        number(e);
    }); 
    $("body").on("change","input[type=text].number,.NUMBER",function(e){
        var t = e.target
        var min = $(t).attr("min");
        var max = $(t).attr("max");
        var val = parseInt($(t).val());         
        if( val<min || max<val)
            {
                alert("Error!");
                $(t).val($(t).data('oldValue'));
            }
    }); 
});
Community
  • 1
  • 1
4

The best way (allow ALL type of numbers - real negative, real positive, iinteger negative, integer positive) is:

$(input).keypress(function (evt){
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode( key );
    var regex = /[-\d\.]/; // dowolna liczba (+- ,.) :)
    var objRegex = /^-?\d*[\.]?\d*$/;
    var val = $(evt.target).val();
    if(!regex.test(key) || !objRegex.test(val+key) || 
            !theEvent.keyCode == 46 || !theEvent.keyCode == 8) {
        theEvent.returnValue = false;
        if(theEvent.preventDefault) theEvent.preventDefault();
    };
}); 
koolo90
  • 11
  • 1
3

Use:

<script>
    function onlyNumber(id){ 
        var DataVal = document.getElementById(id).value;
        document.getElementById(id).value = DataVal.replace(/[^0-9]/g,'');
    }
</script>
<input type="text" id="1" name="1" onChange="onlyNumber(this.id);">

And if you want to update a value after press key, you can change onChange for onKeypress, onKeyDown or onKeyup. But event onKeypress doesn't running in any browsers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rogerio de Moraes
  • 1,527
  • 18
  • 15
3

Code bellow will also check for PASTE event.
Uncomment "ruleSetArr_4" and add(concate) to "ruleSetArr" to allow FLOAT numbers.
Easy copy/paste function. Call it with your input element in parameter.
Example: inputIntTypeOnly($('input[name="inputName"]'))

function inputIntTypeOnly(elm){
    elm.on("keydown",function(event){
        var e = event || window.event,
            key = e.keyCode || e.which,
            ruleSetArr_1 = [8,9,46], // backspace,tab,delete
            ruleSetArr_2 = [48,49,50,51,52,53,54,55,56,57], // top keyboard num keys
            ruleSetArr_3 = [96,97,98,99,100,101,102,103,104,105], // side keyboard num keys
            ruleSetArr_4 = [17,67,86], // Ctrl & V
          //ruleSetArr_5 = [110,189,190], add this to ruleSetArr to allow float values
            ruleSetArr = ruleSetArr_1.concat(ruleSetArr_2,ruleSetArr_3,ruleSetArr_4); // merge arrays of keys
  
            if(ruleSetArr.indexOf() !== "undefined"){ // check if browser supports indexOf() : IE8 and earlier
                var retRes = ruleSetArr.indexOf(key);
            } else { 
                var retRes = $.inArray(key,ruleSetArr);
            };
            if(retRes == -1){ // if returned key not found in array, return false
                return false;
            } else if(key == 67 || key == 86){ // account for paste events
                event.stopPropagation();
            };

    }).on('paste',function(event){
        var $thisObj = $(this),
            origVal = $thisObj.val(), // orig value
            newVal = event.originalEvent.clipboardData.getData('Text'); // paste clipboard value
        if(newVal.replace(/\D+/g, '') == ""){ // if paste value is not a number, insert orig value and ret false
            $thisObj.val(origVal);
            return false;
        } else {
            $thisObj.val(newVal.replace(/\D+/g, ''));
            return false;
        };
  
    });
};

var inptElm = $('input[name="inputName"]');

inputIntTypeOnly(inptElm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" name="inputName" value="1">
crashtestxxx
  • 1,405
  • 5
  • 21
  • 30
3

Here's a nice simple solution that I like to use:

function numeric_only (event, input) {
    if ((event.which < 32) || (event.which > 126)) return true; 
    return jQuery.isNumeric ($(input).val () + String.fromCharCode (event.which));
}// numeric_only;

<input type="text" onkeypress="return numeric_only (event, this);" />

Explanation:

Using "event.which" - first determine if it's a printable character. If it isn't then allow it (for things like delete and backspace). Otherwise, concatinate the character to the end of the string and test it using the jQuery "isNumeric" function. This takes all of the tedium away from testing each individual character and also works for cut / paste scenarios.

If you want to get really cute then you can create a new HTML input type. Let's call it "numeric" so that you can have the tag:

<input type="numeric" />

which will only allow numeric characters. Just add the following "document.ready" command:

$(document).ready (function () {
    $("input[type=numeric]").keypress (function (event) {
        if ((event.which < 32) || (event.which > 126)) return true; 
        return jQuery.isNumeric ($(this).val () + String.fromCharCode (event.which));
    });// numeric.keypress;
});// document.ready;

HTML doesn't care what type name you use - if it doesn't recognize it then it will use a textbox by default, so you can do this. Your editor may complain but, hey, that's its problem. No doubt puritans will freak out, but it works, is easy and so far it's been pretty robust for me.

UPDATE

Here's a better way: it takes text selection into account and uses native javascript:

verify (event) {
    let value = event.target.value;
    let new_value = `${value.substring (0, event.target.selectionStart)}${event.key}${value.substring (event.target.selectionEnd)}`;
    if ((event.code < 32) || (event.code > 126)) return true;
    if (isNaN (parseInt (new_value))) return false;
    return true;
}// verify;
Rex the Strange
  • 133
  • 1
  • 6
3

This is the easy solution

Replace .price-input input.quantity with the class of your input feild

$(".price-input input.quantity").on("keypress keyup blur",function (event) {    
       $(this).val($(this).val().replace(/[^\d].+/, ""));
        if ((event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    });
Aravind Srinivas
  • 320
  • 3
  • 11
3

this also work for persian and arabic number :)

 setNumericInput: function (event) {
          var key = window.event ? event.keyCode : event.which
          if (event.keyCode === 8 ||
        (key >= 48 && key <= 57) ||
        (key >= 1776 && key <= 1785)) {
            return true
          } else {
            event.preventDefault()
          }
        }
hamid keyhani
  • 451
  • 3
  • 12
3

If you are trying on angular this might help

To get the input as number (with a decimal point) then

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

Now this will not update the value in model correctly to explicitly change the value of model too add this

<input [(ngModel)]="data" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" (change)="data = $event.target.value">

The change event will fire after the value in the model has been updated so it can be used with reactive forms as well.

Chirag Jain
  • 75
  • 1
  • 7
3

var userName = document.querySelector('#numberField');

userName.addEventListener('input', restrictNumber);
function restrictNumber (e) {  
  var newValue = this.value.replace(new RegExp(/[^\d]/,'ig'), "");
  this.value = newValue;
}
<input type="text" id="numberField">
3

You can replace the Shurok function with:

$(".numeric").keypress(function() {
    return (/[0123456789,.]/.test(String.fromCharCode(Event.which) ))
});
KapitanX
  • 11
  • 1
2

This removes any bad character instantly, allows only one dot, is short, and allows backspace, etc.:

$('.numberInput').keyup(function () {
    s=$(this).val();
    if (!/^\d*\.?\d*$/.test(s)) $(this).val(s.substr(0,s.length-1));
});
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
wezten
  • 2,126
  • 3
  • 25
  • 48
2

I use the jquery.inputmask.js library you can download from NuGet. More specifically I use jquery.inputmask.regex.extensions.js that comes with it.

I give the input element a class, in this case reg:

<input type="number" id="WorkSrqNo" name="WorkSrqNo" maxlength="6" class="reg"/>

And then in JavaScript I set the mask:

var regexDigitsOnly = "^[0-9]*$";
$('input.reg').inputmask('Regex', { regex: regexDigitsOnly });

This is for digits only, but you can alter the regular expression to accept ".".

By using this it is impossible to enter characters that are not digits. It is useful to have these inputmask libraries for general formatting.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
arame3333
  • 9,887
  • 26
  • 122
  • 205
2

If you are okay with using plugins, here is one I tested. It works well except for paste.

Numeric Input

Here is a Demo http://jsfiddle.net/152sumxu/2

Code below (Lib pasted in-line)

<div id="plugInDemo" class="vMarginLarge">
    <h4>Demo of the plug-in    </h4>
    <div id="demoFields" class="marginSmall">
        <div class="vMarginSmall">
            <div>Any Number</div>
            <div>
                <input type="text" id="anyNumber" />
            </div>
        </div>
    </div>
</div>

<script type="text/javascript">
    //    Author: Joshua De Leon - File: numericInput.js - Description: Allows only numeric input in an element. - If you happen upon this code, enjoy it, learn from it, and if possible please credit me: www.transtatic.com
    (function(b) {
        var c = { allowFloat: false, allowNegative: false};
        b.fn.numericInput = function(e) {
            var f = b.extend({}, c, e);
            var d = f.allowFloat;
            var g = f.allowNegative;
            this.keypress(function(j) {
                var i = j.which;
                var h = b(this).val();
                if (i>0 && (i<48 || i>57)) {
                    if (d == true && i == 46) {
                        if (g == true && a(this) == 0 && h.charAt(0) == "-") {
                            return false
                        }
                        if (h.match(/[.]/)) {
                            return false
                        }
                    }
                    else {
                        if (g == true && i == 45) {
                            if (h.charAt(0) == "-") {
                                return false
                            }
                            if (a(this) != 0) {
                                return false
                            }
                        }
                        else {
                            if (i == 8) {
                                return true
                            }
                            else {
                                return false
                            }
                        }
                    }
                }
                else {
                    if (i>0 && (i >= 48 && i <= 57)) {
                        if (g == true && h.charAt(0) == "-" && a(this) == 0) {
                            return false
                        }
                    }
                }
            });
            return this
        };
        function a(d) {
            if (d.selectionStart) {
                return d.selectionStart
            }
            else {
                if (document.selection) {
                    d.focus();
                    var f = document.selection.createRange();
                    if (f == null) {
                        return 0
                    }
                    var e = d.createTextRange(), g = e.duplicate();
                    e.moveToBookmark(f.getBookmark());
                    g.setEndPoint("EndToStart", e);
                    return g.text.length
                }
            }
            return 0
        }
    }(jQuery));

    $(function() {
       $("#anyNumber").numericInput({ allowFloat: true, allowNegative: true });
    });
</script>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Faiz
  • 5,331
  • 10
  • 45
  • 57
2

Give the input field a class (<input class="digit" ...> ) and use jquery as below .

jQuery(document).ready(function () {
            jQuery('input.digit').live('input keyup',function(e){ jQuery(this).val(jQuery(this).val().replace( /[^\d]/g ,'')); });
});

Above code also works to disable special characters in Ctrl+V strokes and right click strokes also.

Prasanna
  • 81
  • 1
  • 13
2

I might have another (simple) workaround for this...

Since String.fromCharCode(key) returns weird things upon QWERTY keyboard (numerical keypad returns code as g for 1, and 1 for & character ..

I've realized catching the final value on keyup within the input to reset it to an arbitrary value is a simpler, lightweight & bugproof method (could also be done via some regex ... to keep decimals and so on ... don't have to filter other Ctrl, Home, Del, and Enter events...)

Usage with jq :

<input class='pn'>
<script>
function pn(el){nb=el.value;if(isNaN(nb) || nb<1)el.value=1;}
jQuery('.pn').keyup(function(){pn(this);});
</script>

Onkeyup attribute:

<input onkeyup='positiveNumericInput(this)'>
<script>function positiveNumericInput(el){nb=el.value;if(isNaN(nb) || nb<1)el.value=1;}</script>
TheBotlyNoob
  • 369
  • 5
  • 16
Jack
  • 184
  • 1
  • 11
2

You may try using the '''onkeydown''' event and cancel the event (event.preventDefault or something like that) when it's not one of the allowed keys.

mbillard
  • 38,386
  • 18
  • 74
  • 98
2

You can attach to the key down event and then filter keys according to what you need, for example:

<input id="FIELD_ID" name="FIELD_ID" onkeypress="return validateNUM(event,this);"  type="text">

And the actual JavaScript handler would be:

function validateNUM(e,field)
{
    var key = getKeyEvent(e)
    if (specialKey(key)) return true;
    if ((key >= 48 && key <= 57) || (key == 46)){
        if (key != 46)
            return true;
        else{
            if (field.value.search(/\./) == -1 && field.value.length > 0)
                return true;
            else
                return false;
        }
    }

function getKeyEvent(e){
    var keynum
    var keychar
    var numcheck
    if(window.event) // IE
        keynum = e.keyCode
    else if(e.which) // Netscape/Firefox/Opera
        keynum = e.which
    return keynum;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alex Shnayder
  • 1,362
  • 1
  • 13
  • 24
2

Remember the regional differences (Euros use periods and commas in the reverse way as Americans), plus the minus sign (or the convention of wrapping a number in parentheses to indicate negative), plus exponential notation (I'm reaching on that one).

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • Continental Europeans do, anyway. In the UK, and here in Ireland, we use commas and decimal points the same way you do for numbers. Indeed, I think this use of commas and decimal points is common to the entire English-speaking world. – TRiG Jul 01 '10 at 14:58
2

I finished using this function:

onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) return false;"

This works well in IE and Chrome, I don´t know why it´s not work well in firefox too, this function block the tab key in Firefox.

For the tab key works fine in firefox add this:

onkeypress="if(event.which < 48 || event.which > 57 ) if(event.which != 8) if(event.keyCode != 9) return false;"
David
  • 3,285
  • 1
  • 37
  • 54
Edson Cezar
  • 25,884
  • 5
  • 19
  • 27
2
<input type="tel" 
          onkeypress="return onlyNumberKey(event)">

in script tag

function onlyNumberKey(evt) { 
      
      // Only ASCII charactar in that range allowed 
      var ASCIICode = (evt.which) ? evt.which : evt.keyCode 
      if (ASCIICode > 31 && (ASCIICode < 48 || ASCIICode > 57)) 
          return false; 
      return true; 
} 
Ali Raza
  • 670
  • 5
  • 15
2

There is much simplier solution no one mentioned before:

inputmode="numeric"

read more: https://css-tricks.com/finger-friendly-numerical-inputs-with-inputmode/

Atombit
  • 953
  • 9
  • 12
  • According to [Can I Use](https://caniuse.com/input-inputmode) it isn't supported in Firefox and Safari – hurrii Jun 06 '21 at 14:24
2

Got a pretty nice solution. Removes leading zeros, sets the max number of natural and decimal places, handles copy-paste, makes sure that it is a numeric value.

this.value = this.value
    .replace(/\b0+/g, '')
    .replace(/[^0-9.]/g, '')
    .replace(/(\..*?)\..*/g, '$1')
    .replace(/([0-9]{0,6}(\.[0-9]{0,2})?).*/g, '$1')

Last replace sets the length of decimal and natural places. Just replace tokens with your preferred values.

.replace(/([0-9]{0,<max_natural>}(\.[0-9]{0,<max_decimal>})?).*/g, '$1')

Pawel
  • 525
  • 3
  • 16
1

Another easy way with jQuery:

$('.Numeric').bind('keydown',function(e){
    if (e.which < 48 || e.which > 57)
        return false;
    return true;
})

Now just set your each inputs class to Numeric, like:

<input type="text" id="inp2" name="inp2" class='Numeric' />
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ali Mahami
  • 31
  • 4
  • 1
    COPY PASTE from other answer : 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 Feb 22 '13 at 22:01
  • Really bad solution, disables backspace, numeric keypad and others as noted. – c0d3p03t Aug 24 '18 at 18:00
1
function digitsOnly(obj) {
   obj.value = obj.value.replace(/\D/g, "");
}

and in the element

<input type="text" onkeyup="digitsOnly(this);" />
kombi
  • 29
  • 3
1

Yes, HTML5 does. Try this code (w3school):

<!DOCTYPE html>
<html>
<body>

<form action="">
  Quantity (between 1 and 5): <input type="number" name="quantity" min="1" max="5" />
  <input type="submit" />
</form>

</body>
</html>
Gagan Gami
  • 10,121
  • 1
  • 29
  • 55
1

For those of you that like one-liners.

string.replace(/[^\d\.]/g, '').replace(/^\.*/, '').replace(/(\.\d{0,2})(.*)/, '$1');

I use this code on an input type="text", and with AngularJS to activate on keypress, but you can use jQuery if like. Just put this code into a function that activates on a keypress some way.

It only allows digits, digits + decimal, digits + decimal + digits.

CODE

YourString.replace(/[^\d\.]/g, '').replace(/^\.*/, '').replace(/(\.\d{0,2})(.*)/, '$1');

testOne = "kjlsgjkl983724658.346.326.326..36.346"
=> "983724658.34";

testTwo = ".....346...3246..364.3.64.2346......"
=> "346.";

testThree = "slfdkjghsf)_(*(&^&*%^&%$%$%^KJHKJHKJKJH3"
=> "3";

testFour = "622632463.23464236326324363"
=> "622632463.23";

This was built for US currency, but it can be changed to allow more than two decimals past first decimal place as in the following...

CHANGED CODE

YourString.replace(/[^\d\.]/g, '').replace(/^\.*/, '').replace(/(\.\d*)(.*)/, '$1');

testFour = "dfskj345346346.36424362jglkjsg....."
=> "345346346.36424362";

:)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SoEzPz
  • 14,958
  • 8
  • 61
  • 64
1

I was looking for a way to block an input of numbers, then, as I did not find it in answers, this code worked fine for me.

I just need to input it in the onkeypress event.

If you need just to block an input of numbers, I believe this will work fine.

onkeypress="if(event.which &lt; 48 || event.which &gt; 57 ) if(event.which != 8) if(e.keyCode != 9) return false;"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edson Cezar
  • 25,884
  • 5
  • 19
  • 27
1

Here is a very short solution that doesn't use the deprecated keyCode or which, doesn't block any non input keys, and uses pure javascript. (Tested in Chromium 70.0.3533, Firefox 62.0, and Edge 42.17134.1.0)

HTML:

<input type="text" onkeypress="validate(event)">

JS:

function validate(ev) {
    if (!ev) {
        ev = window.event;
    }

    if (!ev.ctrlKey && ev.key.length === 1 && (isNaN(+ev.key) || ev.key === " ")) {
        return ev.preventDefault();
    }
}
8176135
  • 3,755
  • 3
  • 19
  • 42
1

I couldn't find a clear answer, that doesn't loop over the whole string every time, so here:

document.querySelectorAll("input").forEach(input => {
  input.addEventListener("input", e => {
    if (isNaN(Number(input.value[input.value.length-1])) && input.value[input.value.length-1] != '.') {
      input.value = input.value.slice(0, -1);
    }
  })
});

No regex, this goes over the last character every time you type and slices it if it's not a number or period.

benhatsor
  • 1,863
  • 6
  • 20
1

For ReactJS:

<input
    onKeyPress={(event) => {
        if (!/[0-9]/.test(event.key)) {
            event.preventDefault();
        }
    }}
/>

Max Base
  • 639
  • 1
  • 7
  • 15
Bambier
  • 586
  • 10
  • 16
1

Execute this function on any keystroke and it will not allow anything except plus, a hyphen, and parenthesis.

Hypothetical Eg: +234-(123)1231231 will work but not letters

Replace (/^[0-9+()-]*$/.test(char)) with (/^[0-9]*$/.test(char)) to allow only numerics at keystroke.

isNumber(e) {
    let char = String.fromCharCode(e.keyCode);
    if (/^[0-9+()-]*$/.test(char)) return true;
    else e.preventDefault();
},
1

I've used type=tel to be able to limit the number of digits and to allow only digits, I've used the following code:

HTML

<input type="tel" class="form-control number-only" name="Extension" id="Extension" required maxlength="4" minlength="4" placeholder="4 Digits"/>

JQuery

$('.number-only').on('input', (e) => {
  e.target.value = e.target.value.replace(/[^\d]/g, '');
});
Nasser X
  • 175
  • 3
  • 10
0

I tweaked it some, but it needs a lot more work to conform to the JavaScript weirding way.

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

    if (e.shiftKey) {
    } else if (e.altKey) {
    } else if (e.ctrlKey) {
    } else if (key === 48) { // 0
    } else if (key === 49) { // 1
    } else if (key === 50) { // 2
    } else if (key === 51) { // 3
    } else if (key === 52) { // 4
    } else if (key === 53) { // 5
    } else if (key === 54) { // 6
    } else if (key === 55) { // 7
    } else if (key === 56) { // 8
    } else if (key === 57) { // 9

    } else if (key === 96) { // Numeric keypad 0
    } else if (key === 97) { // Numeric keypad 1
    } else if (key === 98) { // Numeric keypad 2
    } else if (key === 99) { // Numeric keypad 3
    } else if (key === 100) { // Numeric keypad 4
    } else if (key === 101) { // Numeric keypad 5
    } else if (key === 102) { // Numeric keypad 6
    } else if (key === 103) { // Numeric keypad 7
    } else if (key === 104) { // Numeric keypad 8
    } else if (key === 105) { // Numeric keypad 9

    } else if (key === 8) { // Backspace
    } else if (key === 9) { // Tab
    } else if (key === 13) { // Enter
    } else if (key === 35) { // Home
    } else if (key === 36) { // End
    } else if (key === 37) { // Left Arrow
    } else if (key === 39) { // Right Arrow
    } else if (key === 190 && decimal) { // decimal
    } else if (key === 110 && decimal) { // period on keypad
    // } else if (key === 188) { // comma
    } else if (key === 109) { // minus
    } else if (key === 46) { // Del
    } else if (key === 45) { // Ins
    } else {
        e.returnValue = false;
        if (e.preventDefault) e.preventDefault();
    }
}

And then it's called via:

$('input[name=Price]').keydown(function(myEvent) {
    validateNumber(myEvent,true);
});
Phillip Senn
  • 46,771
  • 90
  • 257
  • 373
  • This is the best (but large) way to do it, don't block usefull things ! – Korri Feb 22 '13 at 22:04
  • Althought, it doesn't work well for me, on my computer, keycode 100 is 'd' key, and my keypad '4' key is 52, I don't think keycode is really reliable... – Korri Feb 22 '13 at 22:22
0

Call this function when ready to validate what ever. I used a textbox here

In my HTML:

<input type="button" value="Check IT!" onclick="check(document.getElementById('inputboxToValidate').value);" />

In my JavaScript code:

function check(num){
    var onlynumbers = true
    for (var i = 0; i < (num.length - 1); i++) {
        if (num.substr(i, 1) != "0" || num.substr(i, 1) != "1" || num.substr(i, 1) != "2" || num.substr(i, 1) != "3" || num.substr(i, 1) != "4" || num.substr(i, 1) != "5" || num.substr(i, 1) != "6" || num.substr(i, 1) != "7" || num.substr(i, 1) != "8" || num.substr(i, 1) != "9") {
            alert("please make sure that only numbers have been entered in the Quantaty box");
            onlynumbers = false
        }
    }
    if (onlynumbers == true) {

        //Execute Code
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Baladash
  • 1
  • 1
0

Regular expressions and the match function can work well for this situation. For instance, I used the following to validate 4 input boxes that served as coordinates on a graph. It works reasonably well.

function validateInput() {
   if (jQuery('#x1').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null || 
       jQuery('#x2').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null || 
       jQuery('#y1').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null ||
       jQuery('#y2').val().toString().match(/^[-]?[0-9]+[\.]?[0-9]*$/) == null) {
         alert("A number must be entered for each coordinate, even if that number is 0. Please try again.");
         location.reload();
   }
}
0

Thanks guys this really help me!

I found the perfert one really useful for database.

function numonly(root){
    var reet = root.value;    
    var arr1=reet.length;      
    var ruut = reet.charAt(arr1-1);   
        if (reet.length > 0){   
        var regex = /[0-9]|\./;   
            if (!ruut.match(regex)){   
            var reet = reet.slice(0, -1);   
            $(root).val(reet);   
            }   
        }  
 }

Then add the eventhandler:

onkeyup="numonly(this);"
sth
  • 222,467
  • 53
  • 283
  • 367
Alex Homm
  • 41
  • 5
0

When it comes to fool-proofing UX, one should always try to keep a reference point for the 'user's intelligence'.

While neglecting everything other than numbers, a dot and a hyphen would seem like the perfect choice, you should also consider letting them enter any content, and when they're done, purify the input; if not a valid number, show error. This method would make sure no matter what the user manages to do, the result will always be valid. If the user is naive enough not to understand the warnings and error messages, pressing a button and seeing that nothing happens (as in keycode comparison) will only confuse him/her more.

Also, for forms, validation and error message display are almost a necessity. So, the provisions might already be there. Here's the algorithm:

  1. On losing-focus or form-submission, do following.

    1.1. Read content from the input and apply parseFloat to result

    1.2. If the result is a Non-accessible-Number (NaN), reset the input field and pop-up an error message: "Please enter a valid number: eg. 235 or -654 or 321.526 or -6352.646584".

    1.3. Else, if String(result)!==(content from input), change value of the field to result and show warning message: "The value you entered have been modified. Input must be a valid number: eg. 235 or -654 or 321.526 or -6352.646584". For a field that cannot allow any unconfirmed value, then this condition may be added to step 1.2.

    1.4. Else, do nothing.

This method also gives you the added advantage of performing validations based on minimum value, maximum value, decimal places, etc if necessary. Just have to do these operations on the result after step 1.2.

Disadvantages:

  1. The input will allow the user to enter any value until the focus is lost or the form is submitted. But if the instructions on filling the field were clear enough, in 90% of the cases this might not come up.

  2. If step 1.3 is used to display a warning, it might be overlooked by the user and might result in unintentional input submission. Throwing an error or displaying the warning properly would solve this.

  3. Speed. This might be slower in microseconds than the regex method.

Advantages: Assuming the user have basic knowledge to read and understand,

  1. Highly customizable with options.

  2. Works cross browser and independent of language.

  3. Makes use of already available features in a form to display errors and warnings.

BlackPanther
  • 1,732
  • 1
  • 14
  • 19
0

Hope I am not beating a dead horse with an ugly stick here, but I am using this for my website quantity input, it allows only numbers from 1 to 99.

Try it: https://jsfiddle.net/83va5sb9/

      <input min="1" type="text" id="quantity" name="quantity" value="1"
      onKeyUp="numbersonly()">

      <script>
    function numbersonly() {
      var str = document.getElementById("quantity").value
      var newstr = ""
      for (i = 0; i < str.length; i++) {
        for (ii = 1; ii < 10; ii++) {
          if (str.charAt(i).indexOf(ii) > -1) {
            newstr += str.charAt(i)
          }
        }
      }
      if (newstr == "") {
        newstr = 1
      }
      if (parseInt(newstr) > 99) {
        newstr = 99
      }
      document.getElementById("quantity").value = newstr
    }

    </script>
0

Some of the answers above use outdated content, like the use of which.

To check if the pressed key is a number you use a keyup eventListener to read the value of event.key. Then simply prevent the typing of the character if it's not a number. You can whitelist additional keys. Example, allow the user to navigate backward or forwards in the input field with the arrows, or to hit backspace and delete the typed-in numbers.

validate (event) {
  const isNumber = isFinite(event.key)
  const whitelist = ['Backspace','Delete','ArrowDown','ArrowUp','ArrowRight','ArrowLeft']
  const whitelistKey = whitelist.includes(event.key)

  if (!isNumber && !whitelistKey) {
    event.preventDefault()
  }
}
Thomas Van Holder
  • 1,137
  • 9
  • 12
0

Here is an Object-Oriented re-implementation of emkey08's JavaScript Wiki answer which uses an EventListener object implementation. (See: MDN web docs EventListener)

In a way, it prevents duplicating anonymous event handler function declarations for each filtered input element, while still allowing it through an optional call-back.

/**
 * Base input {@see Element} {@see EventListener} filter abstract class
 *
 * @implements EventListener
 */
class AbstractInputFilter {

  /**
   * Attach the input filter to the input {@see Element}
   *
   * @param inputElement The input {@see Element} to filter
   * @param isValid - The callback that determines if the input is valid.
   * @throws Error
   */
  constructor(inputElement, isValid = null) {
    // Abstract class
    if (this.constructor === AbstractInputFilter) {
      throw new Error("Object of Abstract Class cannot be created");
    }

    if (typeof isValid === "function") {
      this.isValid = isValid;
    }

    for (const event of ["input", "keydown", "keyup",
        "mousedown", "mouseup", "select", "contextmenu", "drop"]) {
      inputElement.addEventListener(event, this);
    }
  }

  /**
   * Checks the value is valid
   *
   * @callback isValid default call-back that will throw
   * an {Error} if not implemented by extending this 
   * {AbstractInputFilter} class.
   *
   * @param value The value to check
   * @returns {boolean}
   * @throws Error
   */
  isValid(value) {
    throw new Error('must be implemented by callback!');
  }

  /**
   * Handles the {@see event} dispatched by
   * the {@see EventTarget} object from the input {@see Element}
   * to filter its contant while it is being filled.
   *
   * @param event the {@see event} dispatched by
   * the {@see EventTarget} input {@see Element}
   * @override
   */
  handleEvent(event) {
    const inputElement = event.currentTarget;
    if (this.isValid(inputElement.value)) {
      inputElement.oldValue = inputElement.value;
      inputElement.oldSelectionStart = inputElement.selectionStart;
      inputElement.oldSelectionEnd = inputElement.selectionEnd;
    } else if (inputElement.hasOwnProperty("oldValue")) {
      inputElement.value = inputElement.oldValue;
      inputElement.setSelectionRange(
        inputElement.oldSelectionStart, inputElement.oldSelectionEnd);
    } else {
      this.value = "";
    }
  }
}

/**
 * Generic Input element {@see EventListener} filter
 *
 * @extends AbstractInputFilter
 * It needs the {@see AbstractInputFilter~isValid} callback
 * to determine if the input is valid.
 */
class InputFilter extends AbstractInputFilter {}

/**
 * Unsigned Integer Input element {@see EventListener} filter
 * @extends AbstractInputFilter
 */
class UIntInputFilter extends AbstractInputFilter {
  isValid(value) {
    return /^\d*$/.test(value);
  }
}

/**
 * Unsigned Float Input element {@see EventListener} filter
 * @extends AbstractInputFilter
 */
class UFloatInputFilter extends AbstractInputFilter {
  isValid(value) {
    return /^\d*\.?\d*$/.test(value);
  }
}

// Filter with pre-made InputFilters (re-use the filter)
new UIntInputFilter(document.getElementById("UInt"));
new UFloatInputFilter(document.getElementById("UFloat"));

// Filter with custom callback filter anonymous function
new InputFilter(document.getElementById("AlNum"), function(value) {
  return /^\w*$/.test(value);
});
<label>Unsigned integer: </label><input id="UInt"><br/>
<label>Unsigned float: </label><input id="UFloat"><br/>
<label>AlphaNumeric (no special characters): </label><input id="AlNum">
Léa Gris
  • 17,497
  • 4
  • 32
  • 41
0

input type="tel" works well on mobile devices, so you want to keep that.

Just use the following code (JQuery):

$("input[type=tel]").keydown(function (event) {
        return (event.which >= 48 && event.which <= 57) || //0 TO 9
        event.which === 8 || event.which == 46; //BACKSPACE/DELETE
    });

And your input will be:

<input type="tel" />

And you can add whatever you like to the input field, id, and dont need to bind any other listeneres.

Vinnie Amir
  • 557
  • 5
  • 10
0

use this regex /\D*/g

const phoneHandler = (event: React.ChangeEvent<HTMLInputElement>) =>{
setPhone(event.target.value.replaceAll(/\D*/g, ''));};
Ant1p0w
  • 11
  • 1
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/32209476) – Александр Ермолин Jul 15 '22 at 08:39
0

function isNumeric(event) {
  const keyCode = event.keyCode || event.which;
  const keyValue = String.fromCharCode(keyCode);

  // Allow numeric keys, backspace, delete, and decimal point
  const numericRegex = /[0-9]|\.|Backspace|Delete/;

  if (!numericRegex.test(keyValue)) {
    event.preventDefault();
    return false;
  }
}
<input type="text" id="numericInput" onkeydown="return isNumeric(event)" />
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
0

Look at this answer, hope you could not find any bug. Only numeric input

$(document).on('keydown','input[name^=qtyInvItem_]',function(event){
   var element = this;
    var val = this.value;
   var decimalAllowed = 2;
   if(positiveNumber(event,element,val,decimalAllowed) === false){return false;};
});


  function positiveNumber(event,element,value,allowedDecimalDigits){
    const selectionStart = element.selectionStart;
    const key = event.key;
    var allowedKeys =  [".","0","1","2","3","4","5","6","7","8","9","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","Backspace","Delete","Tab","PageUp","PageDown"];
    var numberKeys = ["0","1","2","3","4","5","6","7","8","9"];
    // prevent double decimal point
    if(key === "." && value.includes(".")){return false;}; 
     // allow allowedKeys
    if(allowedKeys.includes(key) === false){return false;};
    var decimalsPart = value.split(".");
    let part2 = decimalsPart[1]; // get digits after decimal point
    //allow number increase on left side of decimal point and prevent more digits entry on the right side of decimal point
    if(value.indexOf(".") !== -1 && selectionStart > value.indexOf(".") &&  part2.length === allowedDecimalDigits && numberKeys.includes(key)){
    return false;
   }
}
Hafsul Maru
  • 383
  • 2
  • 12
0

I realize an old post but i thought this could help someone. Recently I had to limit a text box to just 5 decimal places. In my case ALSO the users input had to be less than 0.1

<input type="text" value="" maxlength=7 style="width:50px" id="fmargin" class="formText"  name="textfield" onkeyup="return doCheck('#fmargin',event);">

Here is the doCheck function

function doCheck(id,evt)
{
    var temp=parseFloat($(id).val());

    if (isNaN(temp))
        temp='0.0';
    if (temp==0)
        temp='0.0';

    $(id).val(temp);
}

Here is the same function except to force integer input

function doCheck(id,evt)
{
    var temp=parseInt($(id).val());

    if (isNaN(temp))
        temp='0';

    $(id).val(temp);
}

hope that helps someone

ladieu
  • 127
  • 5
  • 17
-1

I have seen many questions that answer this with javascript, but the best answer is to use the type="number" and remove the spin button with css, most of the reason why this is needed is that the spin button doesn't emit the change event when used.

Solution:

HTML

<input type="number" class="input-class">

CSS

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Firefox */
input[type=number] {
  -moz-appearance: textfield;
}
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Martins
  • 1,130
  • 10
  • 26
-1

Here's my one-line solution!

$('#input-field').keypress(e => !String.fromCharCode(e.which).match(/\D/g));
Raofin
  • 31
  • 1
  • 4
-2

I personally suggest to use the autoNumeric plugin from http://www.decorplanit.com/plugin/ - it supports all different variations like prefix/suffix handling, currency handling, negative value formatting, min, max etc.

Philip Helger
  • 1,814
  • 18
  • 28
-3

Below function will check for every input char if it is number.

numeric: value => {
    let numset = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);
    console.log(numset.has(value.substring(value.length - 1, value.length)));
}
Matt Ke
  • 3,599
  • 12
  • 30
  • 49
sau0409
  • 153
  • 1
  • 5