23

i'm making some input mask that allows only float number. But current problem is I can't check if multiple dots entered. Can you check those dots and prevent it for me?

Live Code: http://jsfiddle.net/thisizmonster/VRa6n/

$('.number').keypress(function(event) {
    if (event.which != 46 && (event.which < 47 || event.which > 59))
    {
        event.preventDefault();
        if ((event.which == 46) && ($(this).indexOf('.') != -1)) {
            event.preventDefault();
        }
    }
});
TylerH
  • 20,799
  • 66
  • 75
  • 101
Gereltod
  • 2,043
  • 8
  • 25
  • 39

15 Answers15

41

You can check for the period in the same statement.

Also, you need to use the val method to get the value of the element.

Also, you want to check for the interval 48 to 57, not 47 to 59, otherwise you will also allow /, : and ;.

jQuery(document).ready(function() {
    $('.float-number').keypress(function(event) {
        if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <html>
      <body>
        Enter Number:
        <input type="text" name="number" value="" class="float-number">
      </body>
    </html>
Nirav Sutariya
  • 317
  • 4
  • 14
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • but what about case if first symbol is dot? – user2167382 Apr 11 '14 at 08:54
  • @user2167382: That is only a problem if you specify that it's not allowed. Parsing a string like `'.42'` to a floating point number works just fine. The zero before the period is optional is scientific notation (as long as there are digits after the period of course). – Guffa Apr 11 '14 at 10:17
  • 1
    @RohitSutharYiiExpert: You can add ` && event.which != 8` in the condition to fix that. – Guffa Jan 09 '15 at 09:09
  • @Guffa thanks, also what about in copy-paste situation?? – Rohit Suthar Jan 09 '15 at 11:24
  • @RohitSutharYiiExpert: The keys for that would also have specific key codes, but I think that you should check for what characters you want to disallow rather than which to allow. – Guffa Jan 09 '15 at 11:56
  • this is now allowing to delete by back space after adding some thing in input box. – Naveen Apr 05 '15 at 04:40
  • @Naveen: See the comments by RohitSutharYiiExpert above. – Guffa Apr 05 '15 at 07:41
  • Why is jquery checks necessary considering that guarantees it's a float? – Braiam Jul 18 '22 at 14:57
23

I think you guys have missed the left right arrows, delete and backspace keys.

 $('.number').keypress(function(event) {

     if(event.which == 8 || event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 46) 
          return true;

     else if((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57))
          event.preventDefault();

});
Rohit Suthar
  • 3,528
  • 1
  • 42
  • 48
Desmond
  • 1,308
  • 1
  • 19
  • 27
6

I think everybody forgot the case of pasting text with the mouse, in which you can't detect the keystrokes, because there's none. Here's another approach I have been working on.

// only integer or float numbers (with precision limit)
// example element: <input type="text" value="" class="number" name="number" id="number" placeholder="enter number" />

$('.number').on('keydown keypress keyup paste input', function () {

    // allows 123. or .123 which are fine for entering on a MySQL decimal() or float() field
    // if more than one dot is detected then erase (or slice) the string till we detect just one dot
    // this is likely the case of a paste with the right click mouse button and then a paste (probably others too), the other situations are handled with keydown, keypress, keyup, etc

    while ( ($(this).val().split(".").length - 1) > 1 ) {

        $(this).val($(this).val().slice(0, -1));

        if ( ($(this).val().split(".").length - 1) > 1 ) {
            continue;
        } else {
            return false;
        }

    }

    // replace any character that's not a digit or a dot

    $(this).val($(this).val().replace(/[^0-9.]/g, ''));

    // now cut the string with the allowed number for the integer and float parts
    // integer part controlled with the int_num_allow variable
    // float (or decimal) part controlled with the float_num_allow variable

    var int_num_allow = 3;
    var float_num_allow = 1;

    var iof = $(this).val().indexOf(".");

    if ( iof != -1 ) {

        // this case is a mouse paste (probably also other events) with more numbers before the dot than is allowed
        // the number can't be "sanitized" because we can't "cut" the integer part, so we just empty the element and optionally change the placeholder attribute to something meaningful

        if ( $(this).val().substring(0, iof).length > int_num_allow ) {
            $(this).val('');
            // you can remove the placeholder modification if you like
            $(this).attr('placeholder', 'invalid number');
        }

        // cut the decimal part

        $(this).val($(this).val().substring(0, iof + float_num_allow + 1));

    } else {

        $(this).val($(this).val().substring(0, int_num_allow));

    }

    return true;

});
Carlos Castillo
  • 907
  • 6
  • 7
6

Good for integer and float values. Plus, copy/paste clipboard event.

var el = $('input[name="numeric"]');
el.prop("autocomplete",false); // remove autocomplete (optional)
el.on('keydown',function(e){
 var allowedKeyCodesArr = [9,96,97,98,99,100,101,102,103,104,105,48,49,50,51,52,53,54,55,56,57,8,37,39,109,189,46,110,190];  // allowed keys
 if($.inArray(e.keyCode,allowedKeyCodesArr) === -1 && (e.keyCode != 17 && e.keyCode != 86)){  // if event key is not in array and its not Ctrl+V (paste) return false;
  e.preventDefault();
 } else if($.trim($(this).val()).indexOf('.') > -1 && $.inArray(e.keyCode,[110,190]) != -1){  // if float decimal exists and key is not backspace return fasle;
  e.preventDefault();
 } else {
  return true;
 };  
}).on('paste',function(e){  // on paste
 var pastedTxt = e.originalEvent.clipboardData.getData('Text').replace(/[^0-9.]/g, '');  // get event text and filter out letter characters
 if($.isNumeric(pastedTxt)){  // if filtered value is numeric
  e.originalEvent.target.value = pastedTxt;
  e.preventDefault();
 } else {  // else 
  e.originalEvent.target.value = ""; // replace input with blank (optional)
  e.preventDefault();  // retur false
 };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" name="numeric" value="" placeholder="insert value">

[2017-10-31] Vanilla.js

let el = document.querySelector('input[name="numeric"]');
el.addEventListener('keypress',(event) => {
  let k = event.key,
      t = isNaN(k),
      sc = ['Backspace'].indexOf(k) === -1,
      d = k === '.',dV = el.value.indexOf('.') > -1,
      m = k === '-',mV = el.value.length > 0;

      if((t && sc) && ((d && dV) || (m && dV) || (m && mV) || ((t && !d) && (t && !m)))){event.preventDefault();}
},false);
el.addEventListener('paste',(event) => {
    if(event.clipboardData.types.indexOf('text/html') > -1){
        if(isNaN(event.clipboardData.getData('text'))){event.preventDefault();}
    }
},false);
<input type="text" name="numeric">
crashtestxxx
  • 1,405
  • 5
  • 21
  • 30
3

Your code seems quite fine but overcomplicated.

First, it is $(this).val().indexOf, because you want to do something with the value.

Second, the event.which == 46 check is inside an if clause that's only passed when event.which != 46, which can never be true.

I ended up with this which works: http://jsfiddle.net/VRa6n/3/.

$('.number').keypress(function(event) {
    if(event.which < 46
    || event.which > 59) {
        event.preventDefault();
    } // prevent if not number/dot

    if(event.which == 46
    && $(this).val().indexOf('.') != -1) {
        event.preventDefault();
    } // prevent if already dot
});
pimvdb
  • 151,816
  • 78
  • 307
  • 352
2

HTML

<input type="text"  onkeypress="return isFloatNumber(this,event)" />

Javascript

function isFloatNumber(item,evt) {
    evt = (evt) ? evt : window.event;
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode==46)
    {
        var regex = new RegExp(/\./g)
        var count = $(item).val().match(regex).length;
        if (count > 1)
        {
            return false;
        }
    }
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}

jsfiddle.net

Adrian P.
  • 5,060
  • 2
  • 46
  • 47
Kassem
  • 1,179
  • 8
  • 8
2

I found this way to do this,

$.validator.addMethod("currency", function (value, element) {
  return this.optional(element) || /^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/.test(value);
}, "Please specify a valid amount");

https://gist.github.com/jonkemp/9094324

jacr1614
  • 1,250
  • 2
  • 14
  • 23
1

One-more plugin, based on Carlos Castillo answer

https://github.com/nikita-vanyasin/jquery.numberfield.js

Adds method to jQuery object:

$('input.my_number_field').numberField(options);

where options is (you can pass any or no options):

{
    ints: 2, // digits count to the left from separator
    floats: 6, // digits count to the right from separator
    separator: "."
}
Nikita
  • 21
  • 1
  • 5
1

Using jQuery and allowing negative floats :

// Force floats in '.js_floats_only' inputs
$(document).ready(function() {
    $('.js_floats_only').each(function() {
        // Store starting value in data-value attribute.
        $(this).data('value', this.value);
    });
});

$(document).on('keyup', '.js_floats_only', function() {
    var val = this.value;
    if ( val == '-' ) {
        // Allow starting with '-' symbol.
        return;
    } else {
        if ( isNaN(val) ) {
            // If value is not a number put back previous valid value.
            this.value = $(this).data('value');
        } else {
            // Value is valid, store it inside data-value attribute.
            $(this).data('value', val);
        }
    }
});
1

For simple cases and without hardcoding some html instructions would fit that pretty enough

<input type="number" step="0.01"/>
CodeToLife
  • 3,672
  • 2
  • 41
  • 29
1

Using JQuery.

$(document).ready(function()
     {
        //Only number and one dot
        function onlyDecimal(element, decimals)
        {
            $(element).keypress(function(event)
            {
                num = $(this).val() ;
                num = isNaN(num) || num === '' || num === null ? 0.00 : num ;
                if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57))
                {
                    event.preventDefault();

                }
                if($(this).val() == parseFloat(num).toFixed(decimals))
                {
                    event.preventDefault();
                }
            });
        }

         onlyDecimal("#TextBox1", 3) ;



    });
Adrian
  • 29
  • 1
  • Best solution so far - perhaps an option for beeping if incorrect input? – Hein du Plessis Aug 01 '13 at 10:12
  • but what about case if first symbol is dot(if it is i can input more that number of decimals in function) and why i can't edit inputed decimal if i input 3 digits after point? – user2167382 Apr 11 '14 at 09:16
0
$('.number').keypress(function(event){
            if($.browser.mozilla == true){
                  if (event.which == 8 || event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 9 || event.keyCode == 16 || event.keyCode == 46){
                        return true;
                  }
            }
            if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57)) {
                event.preventDefault();
              }
                });

This works in all browsers.

Praveen
  • 55,303
  • 33
  • 133
  • 164
0
<input type="text" data-textboxtype="numeric" />
<script>
    $(document).on('keydown', '[data-textboxtype="numeric"]', function (e) {
        // Allow: backspace, delete, tab, escape, enter and . and -
        if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190, 109, 189]) !== -1 ||
            // Allow: Ctrl+A
            (e.keyCode == 65 && e.ctrlKey === true) ||
            // Allow: home, end, left, right, down, up
            (e.keyCode >= 35 && e.keyCode <= 40)) {
            // let it happen, don't do anything
            return true;
        }
        // Ensure that it is a number and stop the keypress
        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
            e.preventDefault();
            return false;
        }
        return true;
    });
</script>
Mohammad Dayyan
  • 21,578
  • 41
  • 164
  • 232
0

Below Code I am allowing only Digits and Dot symbol.
ASCII characters number starts in 47 and ends with 58 and dot value is 190.

   $("#Experince").keyup(function (event) {
        debugger

        if ((event.which > 47
            && event.which < 58) ||event.which== 190) {
             if ($("#Experince").val().length > 3) {

        }
        } // prevent if not number/dot
        else {
             $("#Experince").val($("#Experince").val().slice(0, -1))
        }

    });
Hari Lakkakula
  • 199
  • 1
  • 4
0

$('.number').on('keypress', function (event) {
    let text = $(this).val();
    if ((event.which != 46 || $(this).val().indexOf('.') != -1) && ((event.which < 48 || event.which > 57) && (event.which != 0 && event.which != 8))) {
        event.preventDefault();
    }
    if ((text.indexOf('.') != -1) && (text.substring(text.indexOf('.')).length > 2) && (event.which != 0 && event.which != 8) &&
        ($(this)[0].selectionStart >= text.length - 2)) {
        event.preventDefault();
    }
});
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div class="container">
    <h1>Jquery Only Allow Input Float Number</h1>
    <input type="text" name="number" class="number" placeholder="0.00" autocomplete="off">
</div>
Abdo-Host
  • 2,470
  • 34
  • 33