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

3

1

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

Tarpeia answered 11/10, 2019 at 11:23 Comment(6)
Use type="number" and let the browser decide how a number should be formatted correctly for the given location/culture.Donate
Documentation of <input type="number">Respirator
no, I cannot. Because I am using select2. So it is not a real input fieldTarpeia
also with type number I can still write letters inside the fieldTarpeia
@Tarpeia Information like that you are using select2 is important to include in the question.Celestine
But it is a question to the jquery functionTarpeia
N
7

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'>
Namely answered 11/10, 2019 at 11:53 Comment(2)
Thank you, I just realized that I can write "." only one time, but "," I can write multiple timesTarpeia
@chandu What's up bro..Shimkus
L
2
$(".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/

Leisurely answered 11/10, 2019 at 11:45 Comment(2)
I tried your code. I also tried this, but unfortunately still I only can press "." not ","Tarpeia
i have been checked your code i think you should check once is this code works.?Namely
E
2

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's key codes & key identifiers

Disclaimer: I'm the author.

Ejecta answered 27/9, 2020 at 3:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.