如何创建一个只允许数字、逗号和点的输入字段?

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

我正在使用 select2。所以它不是实数输入字段我尝试创建一个只允许带小数的数字的输入字段:

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

我现在需要的是,它不仅允许点,还应该允许逗号。这是我的方法:

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

仍然不允许逗号.. });

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

更多信息:https://keycode.info/

我已经修复了你的代码

 $(".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'>

您不应该监听键盘事件 (keydown / keypress / keyup),因为输入的值也可以通过粘贴或删除文本来更新进入它,有很多你不应该阻止的例外,比如箭头、删除、转义、快捷方式,比如 select 全部、复制、粘贴...

相反,只需监听 input 事件,解析其值以提取其中的所有数字,然后更新其值以仅保留这些数字和一位小数指示符。

一个基本示例如下所示:

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

这样就完成了工作,并且可以很好地粘贴和拖放,但是您会注意到它有两个问题:

  • 输入不该输入的字符时,光标移动

  • 如果您尝试编写第二个小数点指示符,如果新的小数点位于前一个小数点的左侧,它将更新值;如果它在右边,它会保留旧的。

让我们解决这些问题:

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

注意还有一些问题:

  • 如果按一个被过滤掉的键,比如一个字母,光标还是会移动一个位置

  • 如果不是键入小数点分隔符而是粘贴或删除它或包含其中一个或多个的一些文本,保留的仍然是 left-most 那个,这可能不是新的。

但是,这应该为您提供了一个很好的起点来实现您所需要的。

此外,请注意 e.whiche.keyCode 已弃用,因此您应该改用 e.keye.code。您可以使用 https://keyjs.dev:

检查它们的值

免责声明:我是作者。