HTML text input allow only numeric input
Asked Answered
I

79

1112

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

Ivey answered 22/1, 2009 at 14:36 Comment(15)
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!Gadoid
if you do the validation on keyup event, pasting of the user will be validated because auf de keyup of the "v" - key ...Odaniel
@Odaniel - Not if you use the mouse to paste.Doubledealing
I suppose in that case, you will need server-side validation to complement the client javascriptIvey
@JuliusA - you always always need server-side validation anyway.Keldon
<input type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57'></input>Fournier
@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.Lustrum
There is a lot of "html5 will save us" in this thread. Spoiler alert, it doesn't.Poulson
If you are okay with Plugin, use NumericInput. Demo: jsfiddle.net/152sumxu/2 More details here https://mcmap.net/q/46779/-html-text-input-allow-only-numeric-inputWhist
I cannot satisfy with those, so I wrote my own here 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.Interferon
onkeyup="this.value = this.value.replace(/[^0-9]/g, '');" . No HTML5 (caniuse.com/#search=type%3D%22number%22), No Jquery (https://mcmap.net/q/47882/-what-are-some-empirical-technical-reasons-not-to-use-jquery-closed or https://mcmap.net/q/47882/-what-are-some-empirical-technical-reasons-not-to-use-jquery-closed). Good luck for those mapping edition keys, if tomorrow Browsers/OSs add more editing capabilities (imaginary example: like control+* for reverting the character order).Chastain
(Disclaimer: works only for integers, extend the regex for your case)Chastain
one could use onchange event and check the textbox value as isNaN()Fibered
@BennettMcElwee I struggled with it and came up with this solution that includes the copy+paste fixTruda
Quick & dirty: <input name="price" type="text" pattern="[0-9.]*" inputmode="numeric">Danica
E
1357

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>
Exedra answered 22/1, 2009 at 14:36 Comment(13)
Still not supported by Firefox 21 (I don't even talk about IE9 or earlier version ...)Babi
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.Phial
With thanks to all, I wrote another with min and max range. You could see in: #2013729Flocculent
This also allow enter "e" value, I supposed for number with scientific notation 10e3Munt
if you want input in float <input ng-model="dollar" placeholder="Enter Dollar" onkeypress='return event.charCode >= 48 && event.charCode <= 57 || event.charCode == 46'>Balm
2018/10/12, set my inpyt as type='number' or 'tel', but alphanumeric still available for input, tested under newest Chrome and Firefox......Sleuthhound
Chrome plugin "Form Filler" will break this script and will allow just anything to be entered after initial use.Forenoon
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 typeGolliner
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 filtersTrough
use the regex ^\d*(\.|,)?\d*$ if you need additional comma support.Suffragette
why input event alone is not enough?Skyros
"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.)Gadson
DO NOT SET THE input.type to 'text' (at least in firefox it filters the values it passes to your func and messes it upCongener
P
328

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();
  }
}
Photochromy answered 22/1, 2009 at 14:36 Comment(18)
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...Boor
few problems with this code. You can enter . more than one time, second it does not allow delete key, any solution?Rotator
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! :)Alysiaalyson
this is old school now, html 5 spinner widget rocks!Dionysus
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.Babi
Related: "Is there a (built-in) way in JavaScript to check if a string is a valid number?" #176239Berliner
Related too "How to check if a variable is an integer in Javascript?" #14637036Berliner
Live example on how to use the 2 technics above together jsfiddle.net/787j3Berliner
Live example on how to leverage the 2 technics on click button jsfiddle.net/85fbPBerliner
Live example on how to leverage the 2 technics on input type text keyup jsfiddle.net/s58LXBerliner
@Sam i just did this at the start prior to the regex: if (evt.key == "Backspace" || evt.key == "Del") return true;Jacki
Isn't using attributes with javascript deprecated?Interregnum
@Jacki and how about arrows ? and disable the dot ? That would be great.Cognomen
@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)Jacki
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 scriptKilldeer
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)Panay
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. <input type='text' oninput='validate(event)' /> )Glossolalia
For no decimal point, just update to : var regex = /[0-9]/;Bacteriology
D
267

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.

Dearman answered 3/3, 2015 at 18:5 Comment(20)
Handles: copy+paste, drag 'n drop, only allows 1 decimal, tab, delete, backspace - use this oneLattice
Can this logic inside oninput be extracted so that can be used globally?Cysteine
@Cysteine - yes, see my other answer here which shows how you can apply the rule using class.Dearman
if you use this on angular form the value wont update in form control value.Ludlow
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.Voracity
this.value.replace(/[^0-9.]/g, '') replace . from this regex if you don't want to use decimal; value...its wonderful solutionBreathless
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.Zulemazullo
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?Eastsoutheast
@Eastsoutheast - use a delegated event and a class instead of inline oninput event. event example is here. If you have a dynamic page you'll need to change the syntax to a delegated event by putting your input selector after on api.jquery.com/onDearman
I'm late to the party, but wanted to add that this does not handle for leading zerosFlaggy
@Flaggy - 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!Dearman
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.Exurbanite
@Exurbanite - the input is respecting the rules. What would you expect to happen?Dearman
@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.Exurbanite
@Exurbanite - 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.Dearman
@EatenbyaGrue Good point. I'd still go with eliminating consecutive dots, but I guess that's just me.Exurbanite
@Exurbanite = This could be used to do that: this.value = this.value.replace(/[^0-9.]/g, '').replace(/\.\.+/g, '.').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');Dearman
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"))}Birdt
This is the second time I've come here (12/7/2023). I didn't realize this solution was so good during the first time.Sweetandsour
Since type="text" is used, it can be good to also use inputmode="decimal" when we expect the user to enter a decimal number (hint for virtual keyboards, such as those on smartphones).Hydnocarpate
G
174

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) )">
Grig answered 22/1, 2009 at 14:36 Comment(13)
input type="number" is coming in HTML 5 - and you could use JavaScript as a fall-back polyfill... stevefenton.co.uk/Content/Blog/Date/201105/Blog/…Arni
Good method but can be broken by pressing and holding a non-acceptable keyMccusker
Yup, this solution doesn't work when holding down a non-number key.Monarda
Change the regex to /[^\d+]/ and it works with holding downCatwalk
@Catwalk thanks for this, but note that it should be /[^\d]+/ instead. Good solution though. Also @GrigBaluchistan
He wanted to allow . too. You should actually make it /[^0-9.]/gEmbrue
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 ...Babi
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.Eclogue
For the regex you can just do \D instead of [^\d] or [^0-9]. It means "any non-numeric character".Garrick
try to paste "abc", DOESN'T WORK.Duhamel
@DEREKLEE IT ISN'T SUPPOSED TOAtion
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.Chrissy
@Grig - Compactified: <input oninput="this.value=this.value.replace(/(?![0-9]|\.)./gmi,'')"></input>Glossolalia
M
68

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

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

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

function forceNumeric(){
    var $input = $(this);
    $input.val($input.val().replace(/[^\d]+/g,''));
}
$('body').on('propertychange input', 'input[type="number"]', forceNumeric);
Magdalen answered 22/1, 2009 at 14:36 Comment(16)
jQuery 1.7+ needed. This is a more complete answer since it takes in account inputs via "copy". And it is also simpler!Panier
An alternative regex: replace(/[^\d]+/g,'') Replace all non-digits with empty string. The "i" (case insensitive) modifier is not needed.Panier
This should be on top, since "onkey" event handlers in a tag should not be propagated any more...Marya
This one is definitely the best answer here but it doesn't allow digits with decimal numbers. Any idea how that could work?Foudroyant
@Foudroyant If you want decimals you can change the regex /[^\d,.]+/Magdalen
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.Richly
No this is not about HTML5 number input. This answer is about polyfilling said functionality. @RichlyMagdalen
@Magdalen - 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"]?Richly
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'.Leroy
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.Dearman
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...Magdalen
@EJTH: The question, literally was: Is there a quick way to set an HTML text input (<input type=text />) 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.Richly
@Richly I agree this answer is not helpful today. It used to be a handy polyfill for browsers that didn't support number input.Magdalen
I think this is best answer here .. +1Moneymaker
others seem to depend on specific jQuery plugins, which is killing flies with machineguns. Answerer: uses jQuery for the job.Plattdeutsch
why not $('input[type=text]').on('input', forceNumeric);?Skyros
S
59

HTML5 supports regexes, so you could use this:

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

Warning: Some browsers don't support this yet.

Supercolumnar answered 22/1, 2009 at 14:36 Comment(7)
HTML5 also has <input type=number>.Gonfalonier
True. You should make this an answer. Ooops, @Javanese already has.Supercolumnar
The <input type=number> adds arrows for increasing and decreasing in certain browsers so this seems like a good solution when we want to avoid the spinnerCrandell
Pattern only gets checked on submit. You can still enter letters.Petropavlovsk
What does the + means in pattern attribute?Postilion
The + denotes repetition and means "one or more times." See regular-expressions.info/repeat.html.Supercolumnar
@Petropavlovsk Chrome checks patterns on input, not just on submit.Cereus
S
59

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

Sargent answered 22/1, 2009 at 14:36 Comment(12)
Why do I get "event is undefined" when I call this function?Photokinesis
Are you calling validateNumber function on jQuery keypress?Sargent
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; };Ancona
It works as expected, event.keyCode returns code of arrow button key if it is pressedSargent
I would add 9 (tab) and 13 (enter) for the allowed event.keyCode list.Merril
@Merril yes, that make senceSargent
This allows a single quote 'Ation
@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 browserSargent
As @Ation said, you cam add apostrophe and even percentage sign.Stem
Guys, function is updated now, thanks for your comments! Verified on latest Chrome and IE 11Sargent
Very close! but does allow more than one decimal.Antitoxin
Arrow keys don't work :( which then gets you thinking about Home/End, Ctrl+Arrow...Cark
J
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.

Javanese answered 22/1, 2009 at 14:36 Comment(5)
Here's a document defining which browsers support this attribute: caniuse.com/input-number. As of the writing of this, Chrome and Safari both fully support this type field. IE 10 has partial support, and Firefox has no support.Hales
The only problem with type=number is that is not supported by IE9Macedoine
@JRod There's a polyfill for old IE. More info here.Batt
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.Dehlia
Another problem is that if the type is number then I can't get the benefits of setting the type to, for example: "tel".Tesler
D
44

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

<input type="number" />

and

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

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

Dioptometer answered 22/1, 2009 at 14:36 Comment(2)
How about deleting though? You want numbers but you probably want people to be able to correct them without refreshing the page...Conjectural
@MartinErlic I've tried, deleting is normally working. I think this is the best answer.Cyperaceous
A
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);"/ >
Alleris answered 22/1, 2009 at 14:36 Comment(3)
Does not function correctly on keyboards where one has to use the shift key to enter a number (e.g. European AZERTY keyboard).Pard
This is the only one that works that prevent pasting non numeric values.Duhamel
Does not allow paste with any method whatsoever.Mieshamiett
N
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);"/>
Nippers answered 22/1, 2009 at 14:36 Comment(4)
Interestingly, I had to give the regex is "^\\d\\.?\\d*$", but that might be because the page is run through an XSLT transform.Williford
I think the regular expression is incorrect. I used this line: var regExpr = /^\d+(\.\d*)?$/;Pneumonoultramicroscopicsilicovolcanoconiosis
@costa not sure, if the user wants to input .123 (instead of 0.123) for example?Cablet
@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+$/;.Pneumonoultramicroscopicsilicovolcanoconiosis
C
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');">
Cienfuegos answered 22/1, 2009 at 14:36 Comment(0)
H
16

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

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

In your form input:

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

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

Humbug answered 22/1, 2009 at 14:36 Comment(2)
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 !Odysseus
@Odysseus I dont follow, what seems to be the problme? It did work fine in my case.Pillow
H
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.

Hm answered 22/1, 2009 at 14:36 Comment(2)
Wont work in IE8 and 9. See caniuse. Still a good answer.Consistence
You can also add a title="numbers only" to display the errorSybarite
Y
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.

Yugoslavia answered 22/1, 2009 at 14:36 Comment(1)
This indeed seems to cover most casesKillifish
Z
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.

Zippy answered 22/1, 2009 at 14:36 Comment(1)
This allows key "e" and decimal confirmed in chrome.Pollywog
W
12

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

<input type="number">
Wizen answered 22/1, 2009 at 14:36 Comment(0)
A
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.

Anthill answered 22/1, 2009 at 14:36 Comment(0)
L
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"/>


		
Lupelupee answered 22/1, 2009 at 14:36 Comment(0)
S
10

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

<input type="number" maxlength="3" ng-bind="first">
Scullery answered 22/1, 2009 at 14:36 Comment(1)
I haven't check data is --1 (2 minus characters before 1).Andorra
S
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 :)

Skeet answered 22/1, 2009 at 14:36 Comment(0)
C
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)"/>
Churchy answered 22/1, 2009 at 14:36 Comment(0)
W
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.

Wildman answered 22/1, 2009 at 14:36 Comment(4)
I love this! Such an elegant solution, no regex involved.Bryology
This is not an answer to the question, OP asked to only allow text on a input, not verify afterwards.Concatenate
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.Wildman
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.Plattdeutsch
L
8

Just an other variant with jQuery using

$(".numeric").keypress(function() {
    return (/\d/.test(String.fromCharCode(event.which) ))
});
Leonaleonanie answered 22/1, 2009 at 14:36 Comment(0)
M
6
<input name="amount" type="text" value="Only number in here"/> 

<script>
    $('input[name=amount]').keyup(function(){
        $(this).val($(this).val().replace(/[^\d]/,''));
    });
</script>
Moloch answered 22/1, 2009 at 14:36 Comment(0)
P
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.

Primal answered 22/1, 2009 at 14:36 Comment(0)
O
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, ""));
}
Oresund answered 22/1, 2009 at 14:36 Comment(2)
This or any javascript solution has this advantage over <input type="number"> that sometimes the input value is not a number in terms of semantics (It can't be incremented), rather it's a numerical code like one-time passwords.Szombathely
The problem with this approach though is that when you set the type to "text" instead of "number", you lose the number stepper.Guardi
T
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)

Truda answered 22/1, 2009 at 14:36 Comment(0)
S
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);
Solferino answered 22/1, 2009 at 14:36 Comment(0)
A
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();
  }
}
Alysa answered 22/1, 2009 at 14:36 Comment(0)
R
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();
    };
}); 
Remedial answered 22/1, 2009 at 14:36 Comment(0)
L
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'));
            }
    }); 
});
Laundress answered 22/1, 2009 at 14:36 Comment(1)
@UserB this should not delete anything.Steeplejack
P
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">
Povertystricken answered 22/1, 2009 at 14:36 Comment(0)
P
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.

Pinero answered 22/1, 2009 at 14:36 Comment(0)
S
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()
          }
        }
Schrimsher answered 22/1, 2009 at 14:36 Comment(0)
D
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();
        }
    });
Deciduous answered 22/1, 2009 at 14:36 Comment(3)
Thanks bro let me checkDeciduous
Negative prices really ?Deciduous
Your answer may be correct to the questioner. But I am personally looking for the format that can cover minus. So do not care about my comment above too much :DAndorra
O
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;
Ouch answered 22/1, 2009 at 14:36 Comment(0)
S
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">
Salverform answered 22/1, 2009 at 14:36 Comment(0)
S
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.

Satchel answered 22/1, 2009 at 14:36 Comment(1)
This form is native from Javascript + Regular ExpressionSatchel
W
3

You can replace the Shurok function with:

$(".numeric").keypress(function() {
    return (/[0123456789,.]/.test(String.fromCharCode(Event.which) ))
});
Wiatt answered 22/1, 2009 at 14:36 Comment(0)
T
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')

Tientiena answered 22/1, 2009 at 14:36 Comment(0)
I
2

There is much simplier solution no one mentioned before:

inputmode="numeric"

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

Interpol answered 22/1, 2009 at 14:36 Comment(1)
According to Can I Use it isn't supported in Firefox and SafariBurse
P
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; 
} 
Probationer answered 22/1, 2009 at 14:36 Comment(0)
S
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;"
Sectary answered 22/1, 2009 at 14:36 Comment(1)
Works like charm !Boethius
M
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>
Martensite answered 22/1, 2009 at 14:36 Comment(1)
"AZERTY keyboard"? Don't you mean "QWERTY keyboard"?Wellbalanced
M
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.

Meritocracy answered 22/1, 2009 at 14:36 Comment(0)
W
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>
Wellbalanced answered 22/1, 2009 at 14:36 Comment(0)
T
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.

Targett answered 22/1, 2009 at 14:36 Comment(0)
S
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));
});
Saccharate answered 22/1, 2009 at 14:36 Comment(0)
P
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).

Prejudge answered 22/1, 2009 at 14:36 Comment(1)
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.Mosira
N
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;
}
Nador answered 22/1, 2009 at 14:36 Comment(1)
Error: ReferenceError: specialKey is not definedArst
T
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.

Theomachy answered 22/1, 2009 at 14:36 Comment(0)
A
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, '');
});
Archaism answered 22/1, 2009 at 14:36 Comment(0)
L
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();
},
Luciusluck answered 22/1, 2009 at 14:36 Comment(0)
S
1

For ReactJS:

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

Stockbroker answered 22/1, 2009 at 14:36 Comment(1)
This does not allow input deletion. The user needs to refresh the page to enter a different number.Cantwell
A
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.

Alexandraalexandre answered 22/1, 2009 at 14:36 Comment(0)
Z
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();
    }
}
Zoologist answered 22/1, 2009 at 14:36 Comment(1)
THANK YOUUUUU!!! After so many tries, this works!!! many thanks! cheers!Pushball
S
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;"
Sectary answered 22/1, 2009 at 14:36 Comment(0)
L
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";

:)

Ludmilla answered 22/1, 2009 at 14:36 Comment(0)
W
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>
Weinshienk answered 22/1, 2009 at 14:36 Comment(0)
A
1
function digitsOnly(obj) {
   obj.value = obj.value.replace(/\D/g, "");
}

and in the element

<input type="text" onkeyup="digitsOnly(this);" />
Ambrosius answered 22/1, 2009 at 14:36 Comment(0)
S
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' />
Shocking answered 22/1, 2009 at 14:36 Comment(2)
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 !Odysseus
Really bad solution, disables backspace, numeric keypad and others as noted.Ceratodus
C
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;
   }
}
Calla answered 22/1, 2009 at 14:36 Comment(0)
N
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)" />
Nason answered 22/1, 2009 at 14:36 Comment(2)
Delete does not work on FFWizen
backspace doesn't work!Fatso
H
0

use this regex /\D*/g

const phoneHandler = (event: React.ChangeEvent<HTMLInputElement>) =>{
setPhone(event.target.value.replaceAll(/\D*/g, ''));};
Hermineherminia answered 22/1, 2009 at 14:36 Comment(1)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewTufa
P
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.

Privacy answered 22/1, 2009 at 14:36 Comment(0)
G
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">
Graecize answered 22/1, 2009 at 14:36 Comment(0)
M
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()
  }
}
Mckinnie answered 22/1, 2009 at 14:36 Comment(0)
O
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>
Ozonize answered 22/1, 2009 at 14:36 Comment(0)
P
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.

Paulownia answered 22/1, 2009 at 14:36 Comment(0)
O
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();
   }
}
Orthotropous answered 22/1, 2009 at 14:36 Comment(0)
A
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
    }
}
Amitosis answered 22/1, 2009 at 14:36 Comment(0)
P
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);
});
Phonography answered 22/1, 2009 at 14:36 Comment(2)
This is the best (but large) way to do it, don't block usefull things !Odysseus
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...Odysseus
O
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

Orleanist answered 22/1, 2009 at 14:36 Comment(0)
A
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);"
Aisha answered 22/1, 2009 at 14:36 Comment(0)
H
-1

Here's my one-line solution!

$('#input-field').keypress(e => !String.fromCharCode(e.which).match(/\D/g));
Herlindaherm answered 22/1, 2009 at 14:36 Comment(1)
this code is not working.Stratfordonavon
S
-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;
}
Surculose answered 22/1, 2009 at 14:36 Comment(0)
N
-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.

Nebula answered 22/1, 2009 at 14:36 Comment(0)
R
-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)));
}
Rainband answered 22/1, 2009 at 14:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.