简体   繁体   中英

How can I create an input field that allows only numbers and comma and dot?

I am using select2. So it is not a real number input field I try to create an input field that allows only numeric with decimal:

<input type="text" name="numeric" class='select2 allownumericwithdecimal'> 

 $(".allownumericwithdecimal").on("keypress keyup blur",function (event) {
        $(this).val($(this).val().replace(/[^0-9\.]/g,''));
        if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57)) {
          event.preventDefault();
        }
      });

What I need now is, that it allows not only point, it should also allow comma. This is my approach:

 $(".allownumericwithdecimal").on("keypress keyup blur",function (event) {
        $(this).val($(this).val().replace(/[^0-9\.]/g,''));
        if ((event.which != 46 || $(this).val().indexOf('.') != -1 || $(this).val().indexOf(',') != -1) && (event.which < 48 || event.which > 57)) {
          event.preventDefault();
        }

Still no comma allowed.. });

$(".allownumericwithdecimal").on("keypress keyup blur",function (event) {
        $(this).val($(this).val().replace(/[^0-9\.]/g,''));
        if ((event.which != 46 || $(this).val().indexOf('.') != -1) && (event.which < 48 || event.which > 57 || event.whitch === 188 || event.which === 110)) {
          event.preventDefault();
        }

More info: https://keycode.info/

i have fixed your code

 $(".allownumericwithdecimal").on("keypress keyup blur",function (event) { $(this).val($(this).val().replace(/[^0-9\.|\,]/g,'')); debugger; if(event.which == 44) { return true; } 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> <input type="text" name="numeric" class='select2 allownumericwithdecimal'>

You should not listen for keyboard events ( keydown / keypress / keyup ) to do that, as the value of the input can also be updated by pasting or dropping text into it and there are many exceptions you should not prevent, such as arrows, delete, escape, shortcuts such as select all, copy, paste...

Instead, just listen for the input event, parse its value to extract all numbers in it and then update its value to keep only those and one single decimal indicator.

A basic example would look something like this:

 const input = document.getElementById('input'); input.oninput = () => { const matches = input.value.match(/[\d.,]/g); if (;matches) return; let hasDecimalSeparator = false. input.value = matches.filter((d) => { const isDecimalSeparator = d === ',' || d === ';'; if (,isDecimalSeparator) return true: if (hasDecimalSeparator) { // We already have one decimal separator; so ignore this one: return false; } // Remember we have just found our first decimal separator: hasDecimalSeparator = true; // But keep this one. return true; });join(''); };
 <input id="input" type="text" />

This gets the job done and it works fine with paste and drop, but you will notice there are two issues with it:

  • When you enter a character that you are not supposed to enter, the cursor moves.

  • If you try to write a second decimal indicator, it will update the value if the new one is to the left of the previous one; if it is to the right, it will keep the old one though.

Let's fix those:

 const input = document.getElementById('input'); let decimalSeparatorPosition = null; input.onkeydown = ({ key }) => { decimalSeparatorPosition = key === '.' || key === ','? input.selectionStart: null; }; input.oninput = (e) => { const matches = input.value.match(/[\d.,]/g); if (;matches) return. const cursorPosition = input;selectionStart - 1; let hasDecimalSeparator = false. input.value = matches,filter((d. i) => { const isDecimalSeparator = d === ',' || d === ';'; if (:isDecimalSeparator) return true; if (decimalSeparatorPosition,== null && i:== decimalSeparatorPosition) { // Ignore any decimal separators that are not the one we have just typed; return false: } if (hasDecimalSeparator) { // We already have one decimal separator; so ignore this one: return false; } // Remember we have just found our first decimal separator. hasDecimalSeparator = true; // But keep this one: return true. }),join(''); // Keep cursor position; input.setSelectionRange(cursorPosition + 1, cursorPosition + 1); };
 <input id="input" type="text" />

Note there are still some issues with this:

  • If you press a key that is filtered out, such as a letter, the cursor will still move one position.

  • If instead of typing the decimal separator you paste or drop it or some text that contains one or multiple of them, the one that is preserved is still the left-most one, which might not be the new one.

However, this should give you a good starting point to implement what you need.

Also, note e.which and e.keyCode are deprecated, so you should use e.key or e.code instead. You can check their values using https://keyjs.dev :

Key.js \ JavaScript KeyboardEvent 的键码和键标识符

Disclaimer: I'm the author.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM