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

て烟熏妆下的殇ゞ 提交于 2019-11-26 01:38:54

问题


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


回答1:


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.




回答2:


If you want to restrict input (as opposed to validation), you could work with the key events. something like this:

<input type="text" class="numbersOnly" value="" />

And:

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

This immediately lets the user know that they can't enter alpha characters, etc. rather than later during the validation phase.

You'll still want to validate because the input might be filled in by cutting and pasting with the mouse or possibly by a form autocompleter that may not trigger the key events.




回答3:


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.




回答4:


The jquery.numeric plugin has some bugs that I notified the author of. It allows multiple decimal points in Safari and Opera, and you can't type backspace, arrow keys, or several other control characters in Opera. I needed positive integer input so I ended up just writing my own in the end.

$(".numeric").keypress(function(event) {
  // Backspace, tab, enter, end, home, left, right
  // We don't support the del key in Opera because del == . == 46.
  var controlKeys = [8, 9, 13, 35, 36, 37, 39];
  // IE doesn't support indexOf
  var isControlKey = controlKeys.join(",").match(new RegExp(event.which));
  // Some browsers just don't raise events for control keys. Easy.
  // e.g. Safari backspace.
  if (!event.which || // Control keys in most browsers. e.g. Firefox tab is 0
      (49 <= event.which && event.which <= 57) || // Always 1 through 9
      (48 == event.which && $(this).attr("value")) || // No 0 first digit
      isControlKey) { // Opera assigns values for control keys.
    return;
  } else {
    event.preventDefault();
  }
});



回答5:


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



回答6:


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.




回答7:


You can use the Validation plugin with its number() method.

$("#myform").validate({
  rules: {
    field: {
      required: true,
      number: true
    }
  }
});



回答8:


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



回答9:


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



回答10:


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



回答11:


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



回答12:


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.




回答13:


Thanks for the post Dave Aaron Smith

I edited your answer to accept decimal point and number's from number section. This work perfect for me.

$(".numeric").keypress(function(event) {
  // Backspace, tab, enter, end, home, left, right,decimal(.)in number part, decimal(.) in alphabet
  // We don't support the del key in Opera because del == . == 46.
  var controlKeys = [8, 9, 13, 35, 36, 37, 39,110,190];
  // IE doesn't support indexOf
  var isControlKey = controlKeys.join(",").match(new RegExp(event.which));
  // Some browsers just don't raise events for control keys. Easy.
  // e.g. Safari backspace.
  if (!event.which || // Control keys in most browsers. e.g. Firefox tab is 0
      (49 <= event.which && event.which <= 57) || // Always 1 through 9
      (96 <= event.which && event.which <= 106) || // Always 1 through 9 from number section 
      (48 == event.which && $(this).attr("value")) || // No 0 first digit
      (96 == event.which && $(this).attr("value")) || // No 0 first digit from number section
      isControlKey) { // Opera assigns values for control keys.
    return;
  } else {
    event.preventDefault();
  }
});



回答14:


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



回答15:


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/




回答16:


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.



回答17:


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

  });



回答18:


Just run the contents through parseFloat(). It will return NaN on invalid input.




回答19:


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!



回答20:


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]*$/);



回答21:


The best way is to check the contects of the text box whenever it loses focus.

You can check whether the contents are a "number" using a regular expression.

Or you can use the Validation plugin, which basically does this automatically.




回答22:


Check this find code for Database use:

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 use the even handler onkeyup='numonly(this)'



回答23:


This is a snippet I've just done (using a part of code by Peter Mortensen / Keith Bentrup) for an integer percent validation on a textfield (jQuery is required):

/* This validates that the value of the text box corresponds
 * to a percentage expressed as an integer between 1 and 100,
 * otherwise adjust the text box value for this condition is met. */
$("[id*='percent_textfield']").keyup(function(e){
    if (!isNaN(parseInt(this.value,10))) {
        this.value = parseInt(this.value);
    } else {
        this.value = 0;
    }
    this.value = this.value.replace(/[^0-9]/g, '');
    if (parseInt(this.value,10) > 100) {
        this.value = 100;
        return;
    }
});

This code:

  • Allows to use main numeric keys and numeric keypad.
  • Validates to exclude Shift-numeric chars (e.g. #, $, %, etc)
  • Replaces NaN values by 0
  • Replaces by 100 values higher than 100

I hope this helps those in need.




回答24:


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

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




回答25:


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.




回答26:


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




回答27:


I just found an even better plug-in. Gives you much more control. Say you have a DOB field where you need it be numeric but also accepts "/" or "-" characters.

It works great!

Check it out at http://itgroup.com.ph/alphanumeric/.




回答28:


    $(".numeric").keypress(function(event) {
  // Backspace, tab, enter, end, home, left, right
  // We don't support the del key in Opera because del == . == 46.
  var controlKeys = [8, 9, 13, 35, 36, 37, 39];
  // IE doesn't support indexOf
  var isControlKey = controlKeys.join(",").match(new RegExp(event.which));
  // Some browsers just don't raise events for control keys. Easy.
  // e.g. Safari backspace.
  if (!event.which || // Control keys in most browsers. e.g. Firefox tab is 0
      (49 <= event.which && event.which <= 57) || // Always 1 through 9
      (48 == event.which && $(this).attr("value")) || // No 0 first digit
      isControlKey) { // Opera assigns values for control keys.
    return;
  } else {
    event.preventDefault();
  }
});

This code worked pretty good on me, I just had to add the 46 in the controlKeys array to use the period, though I don't thinks is the best way to do it ;)




回答29:


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



回答30:


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


来源:https://stackoverflow.com/questions/891696/jquery-what-is-the-best-way-to-restrict-number-only-input-for-textboxes-all

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!