1041

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

emkey08
  • 3,867
  • 1
  • 31
  • 31
Julius A
  • 35,932
  • 26
  • 72
  • 95
  • 93
    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
  • @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
  • 97
    @JuliusA - you *always* ***always*** need server-side validation anyway. – Stephen P Nov 23 '11 at 01:57
  • 66
  • 18
    @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
    Am I the only one who thinks it's nuts that we have to jump through hoops for such a simple operation? – LarryBud Feb 22 '16 at 14:47
  • 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
  • @Droogans It's also disabled back or delete keys. – Dorbagna May 18 '19 at 13:32
  • Quick & dirty: `` – William Entriken Mar 04 '20 at 17:19

73 Answers73

1303

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

JavaScript

Try it yourself on JSFiddle.

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 input-error class. Here's a suggestion:

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

See the JSFiddle demo for more input filter examples. Also note that you still must do server side validation!

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.

HTML 5

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

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

Try it yourself on w3schools.com.

SuperStormer
  • 4,531
  • 5
  • 20
  • 32
Ian G
  • 28,518
  • 21
  • 75
  • 92
  • 4
    Although this would be a good choice, this still allows to enter characters like /, multiple dots, other operators etc. – Mahendra Liya Mar 12 '13 at 19:36
  • 7
    Still not supported by Firefox 21 (I don't even talk about IE9 or earlier version ...) – JBE May 24 '13 at 17:40
  • From what I can see this only works in Chrome, FF23 just allows text input, and IE10 will allow text input but remove it from the post when sent to the server. IE does highlight when the value is greater than allowed max though. In a nut shell, you can't use type=number to create numeric input. Down voted I'm afraid as it doesn't do what the OP asked. – Morvael Aug 08 '13 at 07:39
  • Just re-read the answer and realized that only the HTML 5 stuff doesn't work. Not tested the script, wish I hadn't down voted now but it won't let me change it.... – Morvael Aug 08 '13 at 08:11
  • 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
  • type="number" also has a strange UI in the browser. Don't expect users to be familiar with it. – Michael Cole Aug 31 '14 at 00:05
  • 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
    the first javascript does not work well for Mozilla Firefox. It disables the left, right, backspace and delete buttons. With IE instead, you can digit '%'% and '&' – Giuseppe Adaldo Nov 03 '14 at 12:44
  • 3
    jQuery variant allows other symbols on keyboard layouts on which there are other symbols on number row, for example AZERTY keyboard or lithuanian keyboard. – Bomberlt Feb 19 '15 at 11:47
  • 6
    The only thing I would add to this is to change the Ctrl+A line to include MacOSX users: `(e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true))` – MForMarlon Mar 17 '15 at 23:06
  • The jQuery variant shortcuts don't work on OS X. Thanks @MForMarlon. – AxeEffect Mar 19 '15 at 15:45
  • 1
    this does not work on macs :( be careful please, i just had a fight with a client because of this – user151496 Aug 06 '15 at 12:33
  • 1
    Some keyboard languages also need the shiftkey to reach te numbers which gets blocked by this script :/ – luwes Aug 07 '15 at 10:39
  • 1
    This also allow enter "e" value, I supposed for number with scientific notation 10e3 – Diego Quirós Nov 04 '15 at 01:05
  • 2
    shift key gets blocked by the script, I am using an IMAC and my keyboard require shift to be able to post numbers, not very useful in my case. – samouray Nov 04 '15 at 09:27
  • 2
    how to allow backspace with it ? – Aamir Jun 23 '16 at 09:36
  • But if I copy some characters and paste that in text field.It is doing so..How to prevent even that – H Varma Dec 12 '16 at 10:14
  • @perfectionist garbage data is fine. An attacker will certainly use something other than garbage data! – jdrake Jan 17 '17 at 06:47
  • @J Drake UI restrictions are meant for user experience, not security. – perfectionist Jan 17 '17 at 11:54
  • Thanks a lot for posting this. In my project (users with a variety of keyboard layouts), I changed the last if to: if (e.key < '0' || e.key > '9') { and it seems to solve the shift-number issue. – savedario Mar 07 '17 at 09:13
  • What about entering numeric characters from other languages (e.g. using French keyboard). – Ithar Mar 28 '17 at 15:52
  • why it cannot run when i paste it on js function? – Adi Prasetyo Jun 07 '17 at 11:09
  • 1
    `return (event.charCode >= 48 && event.charCode <= 57) || event.charCode == 0` had to fix with this for backspace with firefox – user3462015 Jun 10 '17 at 18:23
  • 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
  • How do you implement this using arrow functions, lexical scope? – Eugen Sunic Aug 27 '19 at 07:32
  • 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
  • what about for class. can we use as third params id or class conditions. – Ravi Chauhan Dec 05 '19 at 10:17
  • How to use it with class ( with multi input )? – Yogesh Saroya Apr 25 '20 at 06:51
  • 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
  • why `input` event alone is not enough? – Alex78191 Oct 21 '21 at 06:28
  • Thanks a million! You saved my life :) – Jinwook Kim Dec 26 '21 at 07:21
  • "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
322

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,531
  • 5
  • 20
  • 32
geowa4
  • 38,872
  • 14
  • 87
  • 105
  • 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
  • 3
    change to **if (theEvent.preventDefault) theEvent.preventDefault();** as it's not supported by all browsers – pstanton Oct 24 '09 at 01:25
  • i know its not supported, and i don't care. setting `returnValue` to `false` is the alternative, which i do first. if `preventDefault()` throws an error, i don't care, since it's the last line in the function; no code will be skipped because of the error. – geowa4 Oct 24 '09 at 17:33
  • 11
    Most people do care, having a script error show up reflects poorly on your site. – Robert Jeppesen Apr 26 '10 at 21:37
  • then surround it with another `if` – geowa4 May 13 '11 at 18:29
  • 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
  • 4
    this allow someone paste random stuff to the input – Vitim.us May 04 '12 at 16:39
  • 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 – Adrien Be 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 – Adrien Be Jun 26 '14 at 12:34
  • Live example on how to use the 2 technics above together http://jsfiddle.net/787j3/ – Adrien Be Jun 26 '14 at 13:01
  • Live example on how to leverage the 2 technics on click button http://jsfiddle.net/85fbP/ – Adrien Be Jun 26 '14 at 13:15
  • Live example on how to leverage the 2 technics on input type text keyup http://jsfiddle.net/s58LX/ – Adrien Be 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
  • I updated the answer so that it handles Paste Events properly now. – TetraDev Jun 26 '18 at 23:20
  • 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
195

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

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

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.

Eaten by a Grue
  • 19,208
  • 10
  • 77
  • 99
  • 27
    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. – Eaten by a Grue 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(/(? – 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
  • 1
    Although it does do everything that @Mathemats said, It doesn't handle copy+paste with multiple decimals. All of the decimals of the pasted text get added. – Mr. Simmons Dec 18 '20 at 09:45
  • 2
    @Mr.Simmons - good catch and thanks for pointing that out. I made a small adjustment that should address that scenario. – Eaten by a Grue Dec 18 '20 at 13:29
  • 1
    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/ – Eaten by a Grue 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! – Eaten by a Grue Apr 07 '22 at 21:08
162

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,531
  • 5
  • 20
  • 32
user235859
  • 1,156
  • 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 – Scott Brown 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
66

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);
Eaten by a Grue
  • 19,208
  • 10
  • 77
  • 99
EJTH
  • 2,037
  • 1
  • 18
  • 24
  • 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. – Eaten by a Grue 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
58

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,180
  • 6
  • 35
  • 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
57

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,531
  • 5
  • 20
  • 32
Vasyl
  • 1,244
  • 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
51

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,255
  • 6
  • 78
  • 95
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,092
  • 11
  • 83
  • 106
  • Excellent answer... +1. You can also reduce the if statement to: `return !(charCode > 31 && (charCode < 48 || charCode > 57));` – schadeck Apr 02 '13 at 21:12
  • 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
  • 320
  • 1
  • 4
  • 15
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
  • first line must changed to : `var charCode = (evt.which) ? evt.which : evt.keyCode;` – peiman F. Jul 17 '14 at 22:35
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,408
  • 1
  • 22
  • 37
Romain Linsolas
  • 76,827
  • 47
  • 198
  • 269
  • 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*)?$/;` – costa 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+$/;`. – costa Jan 16 '17 at 19:09
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
  • 18,445
  • 15
  • 88
  • 102
14

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,030
  • 21
  • 100
  • 124
Ashisha Nautiyal
  • 1,379
  • 2
  • 19
  • 39
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.

Shyam Shingadiya
  • 3,267
  • 1
  • 20
  • 39
13

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,535
  • 1
  • 22
  • 36
11

If you want to suggest to the device (maybe a mobile phone) between alpha or numeric you can use <input type="number">.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Steven
  • 61
  • 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
  • 11,721
  • 2
  • 72
  • 50
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,041
  • 3
  • 29
  • 42
AleKennedy
  • 93
  • 2
  • 7
10

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,852
  • 2
  • 18
  • 12
9

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,030
  • 21
  • 100
  • 124
AirWolf
  • 11
  • 1
  • 1
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,030
  • 21
  • 100
  • 124
Vaishali Tekale
  • 101
  • 2
  • 2
8

Just an other variant with jQuery using

$(".numeric").keypress(function() {
    return (/\d/.test(String.fromCharCode(event.which) ))
});
shanethehat
  • 15,360
  • 11
  • 55
  • 85
Shurok
  • 195
  • 1
  • 9
7

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
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,219
  • 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
  • 974
  • 4
  • 16
  • 36
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,030
  • 21
  • 100
  • 124
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,030
  • 21
  • 100
  • 124
Ehsan Chavoshi
  • 632
  • 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
  • 191
  • 2
  • 4
  • 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
5

If I got your question, that's the answer basically

<input type="number">
KTJ
  • 15
  • 1
  • 4
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 17 '21 at 12:50
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,030
  • 21
  • 100
  • 124
Rogerio de Moraes
  • 1,509
  • 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,319
  • 5
  • 20
  • 29
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
  • 123
  • 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
  • 10
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
  • 374
  • 2
  • 11
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

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,030
  • 21
  • 100
  • 124
wezten
  • 1,756
  • 3
  • 21
  • 43
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,030
  • 21
  • 100
  • 124
arame3333
  • 9,477
  • 25
  • 112
  • 198
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,030
  • 21
  • 100
  • 124
Faiz
  • 5,181
  • 10
  • 43
  • 55
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
  • 83
  • 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
  • 331
  • 5
  • 13
Jack
  • 164
  • 1
  • 10
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
  • 37,328
  • 18
  • 74
  • 97
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,030
  • 21
  • 100
  • 124
Alex Shnayder
  • 1,352
  • 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
  • 72,855
  • 39
  • 185
  • 327
  • 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,255
  • 1
  • 33
  • 53
Edson Cezar
  • 22,484
  • 5
  • 17
  • 25
2

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">
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
  • 502
  • 2
  • 10
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
  • 840
  • 8
  • 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
  • 495
  • 3
  • 11
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,030
  • 21
  • 100
  • 124
Ali Mahami
  • 31
  • 3
  • 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
  • 1
  • 1
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
  • 9,916
  • 1
  • 27
  • 54
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,030
  • 21
  • 100
  • 124
SoEzPz
  • 13,409
  • 8
  • 60
  • 61
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,030
  • 21
  • 100
  • 124
Edson Cezar
  • 22,484
  • 5
  • 17
  • 25
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
  • 2,983
  • 15
  • 38
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.

barhatsor
  • 1,635
  • 5
  • 19
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
  • 44,943
  • 87
  • 252
  • 365
  • 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,030
  • 21
  • 100
  • 124
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
  • 211,504
  • 50
  • 270
  • 362
Alex Homm
  • 31
  • 4
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,663
  • 1
  • 13
  • 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()
  }
}
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
  • 14,880
  • 4
  • 28
  • 36
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
  • 457
  • 5
  • 10
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
  • 128
  • 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
  • 11,885
  • 5
  • 66
  • 81
Martins
  • 979
  • 8
  • 21
-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,755
  • 17
  • 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,119
  • 10
  • 28
  • 46
sau0409
  • 133
  • 5