1126

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

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

79 Answers 79

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();
    };
}); 
Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

@UserB this should not delete anything.
3

You can replace the Shurok function with:

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

Comments

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

Comments

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.

1 Comment

This form is native from Javascript + Regular Expression
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();
        }
    });

3 Comments

Thanks bro let me check
Negative prices really ?
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 :D
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()
          }
        }

Comments

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.

Comments

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

Comments

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;

Comments

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.

Comments

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

1 Comment

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.
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.

Comments

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

Comments

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.

Comments

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>

Comments

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

1 Comment

Error: ReferenceError: specialKey is not defined
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;"

1 Comment

Works like charm !
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; 
} 

Comments

2

There is much simplier solution no one mentioned before:

inputmode="numeric"

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

1 Comment

According to Can I Use it isn't supported in Firefox and Safari
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>

1 Comment

"AZERTY keyboard"? Don't you mean "QWERTY keyboard"?
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')

Comments

1
function digitsOnly(obj) {
   obj.value = obj.value.replace(/\D/g, "");
}

and in the element

<input type="text" onkeyup="digitsOnly(this);" />

Comments

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>

Comments

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

:)

Comments

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

Comments

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

2 Comments

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 !
Really bad solution, disables backspace, numeric keypad and others as noted.
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();
    }
}

1 Comment

THANK YOUUUUU!!! After so many tries, this works!!! many thanks! cheers!
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.

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.