wenbert
wenbert

Reputation: 5303

jQuery: what is the best way to restrict "number"-only input for textboxes? (allow decimal points)

What is the best way to restrict "number"-only input for textboxes?

I am looking for something that allows decimal points.

I see a lot of examples. But have yet to decide which one to use.

Update from Praveen Jeganathan

No more plugins, jQuery has implemented its own jQuery.isNumeric() added in v1.7. See: https://stackoverflow.com/a/20186188/66767

Upvotes: 237

Views: 616630

Answers (30)

tksilicon
tksilicon

Reputation: 4456

I used James Nelli answer and added onpaste="return false;" (Håvard Geithus) to ensure only integer is entered into the input. Even if you tried to paste, it will not allow it.

Upvotes: 1

TheVillageIdiot
TheVillageIdiot

Reputation: 40512

Update

There is a new and very simple solution for this:

It allows you to use any kind of input filter on a text <input>, including various numeric filters. This will correctly handle Copy+Paste, Drag+Drop, keyboard shortcuts, context menu operations, non-typeable keys, and all keyboard layouts.

See this answer or try it yourself on JSFiddle.

jquery.numeric plugin

I've successfully implemented many forms with the jquery.numeric plugin.

$(document).ready(function(){
    $(".numeric").numeric();
});

Moreover this works with textareas also!

However, note that Ctrl+A, Copy+Paste (via context menu) and Drag+Drop will not work as expected.

HTML 5

With wider support for the HTML 5 standard, we can use pattern attribute and number type for input elements to restrict number only input. In some browsers (notably Google Chrome), it works to restrict pasting non-numeric content as well. More information about number and other newer input types is available here.

Upvotes: 200

jBelanger
jBelanger

Reputation: 1788

You can use HTML5 validation on your text inputs by adding a pattern. No need to manually validate with regex or keyCodes.

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

$("input[type=text][pattern]").on("input", function () {
    if (!this.checkValidity())
        this.value = this.value.slice(0, -1);
});

For a solution with input [type=number], see my full answer here

Upvotes: 0

roger
roger

Reputation: 71

/* this is my cross browser version of How to allow only numeric (0-9) in HTML inputbox using jQuery?
*/

$("#inputPrice").keydown(function(e){
    var keyPressed;
    if (!e) var e = window.event;
    if (e.keyCode) keyPressed = e.keyCode;
    else if (e.which) keyPressed = e.which;
    var hasDecimalPoint = (($(this).val().split('.').length-1)>0);
    if ( keyPressed == 46 || keyPressed == 8 ||((keyPressed == 190||keyPressed == 110)&&(!hasDecimalPoint && !e.shiftKey)) || keyPressed == 9 || keyPressed == 27 || keyPressed == 13 ||
             // Allow: Ctrl+A
            (keyPressed == 65 && e.ctrlKey === true) ||
             // Allow: home, end, left, right
            (keyPressed >= 35 && keyPressed <= 39)) {
                 // let it happen, don't do anything
                 return;
        }
        else {
            // Ensure that it is a number and stop the keypress
            if (e.shiftKey || (keyPressed < 48 || keyPressed > 57) && (keyPressed < 96 || keyPressed > 105 )) {
                e.preventDefault();
            }
        }

  });

Upvotes: 4

Agnibha
Agnibha

Reputation: 693

I have this piece of code that does the job very well for me.

 var prevVal = '';
$(".numericValue").on("input", function (evt) {
    var self = $(this);
    if (self.val().match(/^-?\d*(\.(?=\d*)\d*)?$/) !== null) {
        prevVal = self.val()
    } else {
        self.val(prevVal);
    }
    if ((evt.which != 46 || self.val().indexOf('.') != -1) && (evt.which < 48 || evt.which > 57) && (evt.which != 45 && self.val().indexOf("-") == 0)) {
        evt.preventDefault();
    }
});

Upvotes: 0

Muhammad Inaam Munir
Muhammad Inaam Munir

Reputation: 1260

ALLOWS NEGATIVE NUMBERS ALSO

Following code also accepts negative numbers

HTML

<input type="text" name="myText" />

JS

var pastValue, pastSelectionStart, pastSelectionEnd;

$("input").on("keydown", function() {
    pastValue          = this.value;
    pastSelectionStart = this.selectionStart;
    pastSelectionEnd   = this.selectionEnd;
}).on("input propertychange", function() {

    if ( this.value.length > 0 && $.isNumeric(this.value) == false && this.value != '-' ) {
        this.value          = pastValue;
        this.selectionStart = pastSelectionStart;
        this.selectionEnd   = pastSelectionEnd;
    }
}).on('blur', function(){
        if(this.value == '-')
            this.value = '';
});

Upvotes: 0

Mladen Adamovic
Mladen Adamovic

Reputation: 3211

HTML5 supports input type number with global browser support 88%+ according to CanIUse as of Oct 2015.

<input type="number" step="0.01" min="0" name="askedPrice" id="askedPrice" />

This is not JQuery related solution, but the advantage is that on mobile phones Android keyboard will be optimized for entering numbers.

Alternatively, it is possible to use input type text with new parameter "pattern". More details in HTML5 spec.

I think it is better than jquery solution, since in this question provided jquery solution do not support thousands separator. If you can use html5.

JSFiddle: https://jsfiddle.net/p1ue8qxj/

Upvotes: 4

samurai
samurai

Reputation: 68

Using Keypress Event

  1. Array Method
var asciiCodeOfNumbers = [48, 49, 50, 51, 52, 53, 54, 54, 55, 56, 57]
$(".numbersOnly").keypress(function (e) {
        if ($.inArray(e.which, asciiCodeOfNumbers) == -1)
            e.preventDefault();
    });
  1. Direct Method
$(".numbersOnly").keypress(function (e) {
        if (e.which < 48 || 57 < e.which)
            e.preventDefault();
    });

Upvotes: 1

Carlos Toledo
Carlos Toledo

Reputation: 2714

Other way to keep the caret position on the input:

$(document).ready(function() {
  $('.numbersOnly').on('input', function() {
    var position = this.selectionStart - 1;

    fixed = this.value.replace(/[^0-9\.]/g, '');  //remove all but number and .
    if(fixed.charAt(0) === '.')                  //can't start with .
      fixed = fixed.slice(1);

    var pos = fixed.indexOf(".") + 1;
    if(pos >= 0)
      fixed = fixed.substr(0,pos) + fixed.slice(pos).replace('.', '');  //avoid more than one .

    if (this.value !== fixed) {
      this.value = fixed;
      this.selectionStart = position;
      this.selectionEnd = position;
    }
  });
});

Advantages:

  1. The user can use the arrow keys, Backspace, Delete, ...
  2. Works when you want to paste numbers

Plunker: Demo working

Upvotes: 2

David
David

Reputation: 532

There's a nice jquery plugin called Jquery Mask Plugin that designed to make masks on form fields and html elements, but you can also used it to simply define what kind of data could be typed inside of a field:

$('.numeric-input').mask('0#');

Now only numbers will be allowed inside your form field.

Upvotes: 1

vinayakj
vinayakj

Reputation: 5681

No need for the long code for number input restriction just try this code.

It also accepts valid int & float both values.

Javascript Approach

onload =function(){ 
  var ele = document.querySelectorAll('.number-only')[0];
  ele.onkeypress = function(e) {
     if(isNaN(this.value+""+String.fromCharCode(e.charCode)))
        return false;
  }
  ele.onpaste = function(e){
     e.preventDefault();
  }
}
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

jQuery Approach

$(function(){

  $('.number-only').keypress(function(e) {
	if(isNaN(this.value+""+String.fromCharCode(e.charCode))) return false;
  })
  .on("cut copy paste",function(e){
	e.preventDefault();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

UPDATE

The above answers are for most common use case - validating input as a number.

But below is the code snippet for special use cases

  • Allowing negative numbers
  • Showing the invalid keystroke before removing it.

$(function(){
      
  $('.number-only').keyup(function(e) {
        if(this.value!='-')
          while(isNaN(this.value))
            this.value = this.value.split('').reverse().join('').replace(/[\D]/i,'')
                                   .split('').reverse().join('');
    })
    .on("cut copy paste",function(e){
    	e.preventDefault();
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p> Input box that accepts only valid int and float values.</p>
<input class="number-only" type=text />

Upvotes: 19

Praveen
Praveen

Reputation: 56549

No more plugins, jQuery has implemented its own jQuery.isNumeric() added in v1.7.

jQuery.isNumeric( value )

Determines whether its argument is anumber.

Samples results

$.isNumeric( "-10" );     // true
$.isNumeric( 16 );        // true
$.isNumeric( 0xFF );      // true
$.isNumeric( "0xFF" );    // true
$.isNumeric( "8e5" );     // true (exponential notation string)
$.isNumeric( 3.1415 );    // true
$.isNumeric( +10 );       // true
$.isNumeric( 0144 );      // true (octal integer literal)
$.isNumeric( "" );        // false
$.isNumeric({});          // false (empty object)
$.isNumeric( NaN );       // false
$.isNumeric( null );      // false
$.isNumeric( true );      // false
$.isNumeric( Infinity );  // false
$.isNumeric( undefined ); // false

Here is an example of how to tie the isNumeric() in with the event listener

$(document).on('keyup', '.numeric-only', function(event) {
   var v = this.value;
   if($.isNumeric(v) === false) {
        //chop off the last char entered
        this.value = this.value.slice(0,-1);
   }
});

Upvotes: 49

David Sherret
David Sherret

Reputation: 106880

I think this is a good way of solving this problem and it's extremely simple:

$(function() {
    var pastValue, pastSelectionStart, pastSelectionEnd;

    $("input").on("keydown", function() {
        pastValue          = this.value;
        pastSelectionStart = this.selectionStart;
        pastSelectionEnd   = this.selectionEnd;
    }).on("input propertychange", function() {
        var regex = /^[0-9]+\.?[0-9]*$/;

        if (this.value.length > 0 && !regex.test(this.value)) {
            this.value          = pastValue;
            this.selectionStart = pastSelectionStart;
            this.selectionEnd   = pastSelectionEnd;
        }
    });
});

Example: JSFiddle

Scenarios covered

Most similar recommendations here fail at least one of these or require a lot of code to cover all these scenarios.

  1. Only allows 1 decimal point.
  2. Allows home, end, and the arrow keys.
  3. Allows delete and backspace to be used at any index.
  4. Allows editing at any index (as long as the input matches the regex).
  5. Allows ctrl+v and shift+insert for valid input (same with right click + paste).
  6. Doesn't flicker the text value because the keyup event is not used.
  7. Restores the selection after invalid input.

Scenarios failed

  • Starting with 0.5 and deleting only the zero will not work. This can be fixed by changing the regex to /^[0-9]*\.?[0-9]*$/ and then adding a blur event to prepend a 0 when the textbox starts with a decimal point (if desired). See this advanced scenario for a better idea of how to fix this.

Plugin

I created this simple jquery plugin to make this easier:

$("input").limitRegex(/^[0-9]+\.?[0-9]*$/);

Upvotes: 3

Jay Blanchard
Jay Blanchard

Reputation: 34426

If you're using HTML5 you don't need to go to any great lengths to perform validation. Just use -

<input type="number" step="any" />

The step attribute allows the decimal point to be valid.

Upvotes: 3

H&#229;vard Geithus
H&#229;vard Geithus

Reputation: 5634

I first tried solving this using jQuery, but I wasn't happy about unwanted characters (non-digits) actually appearing in the input field just before being removed on keyup.

Looking for other solutions I found this:

Integers (non-negative)

<script>
  function numbersOnly(oToCheckField, oKeyEvent) {
    return oKeyEvent.charCode === 0 ||
        /\d/.test(String.fromCharCode(oKeyEvent.charCode));
  }
</script>

<form name="myForm">
<p>Enter numbers only: <input type="text" name="myInput" 
    onkeypress="return numbersOnly(this, event);" 
    onpaste="return false;" /></p>
</form>

Source: https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onkeypress#Example Live example: http://jsfiddle.net/u8sZq/

Decimal points (non-negative)

To allow a single decimal point you could do something like this:

<script>
  function numbersOnly(oToCheckField, oKeyEvent) {        
    var s = String.fromCharCode(oKeyEvent.charCode);
    var containsDecimalPoint = /\./.test(oToCheckField.value);
    return oKeyEvent.charCode === 0 || /\d/.test(s) || 
        /\./.test(s) && !containsDecimalPoint;
  }
</script>

Source: Just wrote this. Seems to be working. Live example: http://jsfiddle.net/tjBsF/

Other customizations

  • To allow more symbols to be typed just add those to the regular expression that is acting as the basic char code filter.
  • To implement simple contextual restrictions, look at the current content (state) of the input field (oToCheckField.value)

Some things you could be interested in doing:

  • Only one decimal point allowed
  • Allow minus sign only if positioned at the start of the string. This would allow for negative numbers.

Shortcomings

  • The caret position is not available inside the function. This greatly reduced the contextual restrictions you can implement (e.g. no two equal consecutive symbols). Not sure what the best way to access it is.

I know the title asks for jQuery solutions, but hopefully someone will find this useful anyway.

Upvotes: 8

David Freire
David Freire

Reputation: 671

   window.jQuery.fn.ForceNumericOnly =
       function () {

           return this.each(function () {
               $(this).keydown(function (event) {
                   // Allow: backspace, delete, tab, escape, and enter
                   if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 ||
                       // Allow: Ctrl+A
                       (event.keyCode == 65 && event.ctrlKey === true) ||
                       // Allow: home, end, left, right
                       (event.keyCode >= 35 && event.keyCode <= 39)) {
                       // let it happen, don't do anything
                       return;
                   } else {
                       // Ensure that it is a number and stop the keypress
                       if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                           event.preventDefault();
                       }
                   }
               });
           });
       };

And apply this on all the inputs you want:

$('selector').ForceNumericOnly();

Upvotes: 6

kamal.shalabe
kamal.shalabe

Reputation: 129

i use that function and it works fine

$(document).ready(function () {
        $("#txt_Price").keypress(function (e) {
            //if the letter is not digit then display error and don't type anything
            //if (e.which != 8 && e.which != 0 && (e.which < 48 || e.which > 57)) 
            if ((e.which != 46 || $(this).val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) {
                //display error message
                $("#errmsg").html("Digits Only").show().fadeOut("slow");
                return false;
            }
        });
    }); 

Upvotes: 1

Praveen04
Praveen04

Reputation: 993

This code belongs to restrict alphabets in text boxes,have to enter oly number validate on keypress event.Hope it will help for you

HTML Tags:

<input id="txtPurchaseAmnt" style="width:103px" type="text" class="txt" maxlength="5" onkeypress="return isNumberKey(event);" />

function onlyNumbers(key) {

        var keycode = (key.which) ? key.which : key.keyCode

        if ((keycode > 47 && keycode < 58) || (keycode == 46 || keycode == 8) || (keycode == 9 || keycode == 13) || (keycode == 37 || keycode == 39)) {

            return true;
        }
        else {
            return false;
        }
    }

Upvotes: 0

Mike Gibbs
Mike Gibbs

Reputation: 361

The numeric() plugin mentioned above, doesn't work in Opera (you can't backspace, delete or even use the back or forward keys).

The code below in both JQuery or Javascript will work perfectly (and it's only two lines).

JQuery:

$(document).ready(function() {
    $('.key-numeric').keypress(function(e) {
            var verified = (e.which == 8 || e.which == undefined || e.which == 0) ? null : String.fromCharCode(e.which).match(/[^0-9]/);
            if (verified) {e.preventDefault();}
    });
});

Javascript:

function isNumeric(e)
{
    var keynum = (!window.event) ? e.which : e.keyCode;
    return !((keynum == 8 || keynum == undefined || e.which == 0) ? null : String.fromCharCode(keynum).match(/[^0-9]/));
}

Of course this is for pure numeric input (plus backspace, delete, forward/back keys) only but can easily be changed to include points and minus characters.

Upvotes: 36

Tabbernaut
Tabbernaut

Reputation: 76

The jquery.numeric plugin works well for me too.

The only thing I dislike has to do with intuitiveness. Keypresses get 'disallowed' without any feedback to the user, who might get paranoid or wonder whether his keyboard is broken.

I added a second callback to the plugin to make simple feedback on blocked input possible:

$('#someInput').numeric(
    null, // default config
    null, // no validation onblur callback
    function(){
        // for every blocked keypress:
        $(this).effect("pulsate", { times:2 }, 100);
    }
);

Just an example (using jQuery UI), of course. Any simple visual feedback would help.

Upvotes: 1

Brad Parks
Brad Parks

Reputation: 72303

As a slight improvement to this suggestion, you can use the Validation plugin with its number(), digits, and range methods. For example, the following ensures you get a positive integer between 0 and 50:

$("#myform").validate({
  rules: {
    field: {
      required: true,
      number: true,
      digits: true,
      range : [0, 50]
    }
  }
});

Upvotes: 11

Null Head
Null Head

Reputation: 2941

You dont see alphabets magical appearance and disappearance on key down. This works on mouse paste too.

$('#txtInt').bind('input propertychange', function () {
    $(this).val($(this).val().replace(/[^0-9]/g, ''));
});

Upvotes: 9

Jyothu
Jyothu

Reputation: 3154

This is very simple that we have already a javascript inbuilt function "isNaN" is there.

$("#numeric").keydown(function(e){
  if (isNaN(String.fromCharCode(e.which))){ 
    return false; 
  }
});

Upvotes: 1

kaleazy
kaleazy

Reputation: 6242

Below is what I use to literally block the keystrokes. This only allows numbers 0-9 and a decimal point. Easy to implement, not a lot of code, and works like a charm:

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

<input value="" onkeypress="return isNumberKey(event)">

Upvotes: 14

Mithil
Mithil

Reputation: 3770

Found a great solution here http://ajax911.com/numbers-numeric-field-jquery/

I just changed the "keyup" to "keydown" as per my requirement

Upvotes: 2

James Nelli
James Nelli

Reputation: 1129

I thought that the best answer was the one above to just do this.

jQuery('.numbersOnly').keyup(function () {  
    this.value = this.value.replace(/[^0-9\.]/g,''); 
});

but I agree that it is a bit of a pain that the arrow keys and delete button snap cursor to the end of the string ( and because of that it was kicked back to me in testing)

I added in a simple change

$('.numbersOnly').keyup(function () {
    if (this.value != this.value.replace(/[^0-9\.]/g, '')) {
       this.value = this.value.replace(/[^0-9\.]/g, '');
    }
});

this way if there is any button hit that is not going to cause the text to be changed just ignore it. With this you can hit arrows and delete without jumping to the end but it clears out any non numeric text.

Upvotes: 105

Kaustubh
Kaustubh

Reputation: 1505

I used this,with good results..

ini=$("#id").val();
a=0;
$("#id").keyup(function(e){
    var charcode = (e.which) ? e.which : e.keyCode;
    // for decimal point
    if(!(charcode===190 || charcode===110))
    {           // for numeric keys andcontrol keys
        if (!((charcode>=33 && charcode<=57) || 
        // for numpad numeric keys
        (charcode>=96 && charcode<=105) 
        // for backspace
        || charcode==8)) 
        {
            alert("Sorry! Only numeric values allowed.");
            $("#id").val(ini);
        }
        // to include decimal point if first one has been deleted.
        if(charcode===8)
        {
            ini=ini.split("").reverse();
            if(ini[0]==".")
            a=0;                 
        }
    }
    else
    {
        if(a==1)
        {
            alert("Sorry! Second decimal point not allowed.");
            $("#id").val(ini);
        }
        a=1;
    }
    ini=$("#id").val();
});


find keycodes at http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes

Upvotes: 1

Zero Distraction
Zero Distraction

Reputation: 1356

You can use autoNumeric from decorplanit.com . They have a nice support for numeric, as well as currency, rounding, etc.

I have used in an IE6 environment, with few css tweaks, and it was a reasonable success.

For example, a css class numericInput could be defined, and it could be used to decorate your fields with the numeric input masks.

adapted from autoNumeric website:

$('input.numericInput').autoNumeric({aSep: '.', aDec: ','}); // very flexible!

Upvotes: 3

mordy
mordy

Reputation: 1045

This function does the same thing, uses some of the ideas above.

$field.keyup(function(){
    var val = $j(this).val();
    if(isNaN(val)){
         val = val.replace(/[^0-9\.]/g,'');
         if(val.split('.').length>2) val =val.replace(/\.+$/,"");
    }
    $j(this).val(val); 
});
  • show visual feedback (incorrect letter appears before disappearing)
  • allows decimals
  • catches multiple "."
  • has no issues with left/right del etc.

Upvotes: 4

Fabian Ramirez
Fabian Ramirez

Reputation: 13

Please add in the bottom of the script:

if(this.value.length == 1 && this.value == 0)
 this.value = "";

Upvotes: -4

Related Questions