简体   繁体   English

淘汰赛-将输入限制为仅带小数点的数字

[英]Knockout - restrict input to only numbers with one decimal point

I have the code below which does restrict the input to only numbers and a select number of key combinations. 我下面的代码确实将输入限制为仅数字和选定数量的组合键。 But I also want to restrict the input to only accept one decimal point. 但我也想将输入限制为只接受一个小数点。

number: {
            init: function (element) {
                // Allows only numbers with decimals
                $(element).on("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, Ctrl + C, Ctrl + V, Ctrl + X
                        ((event.keyCode === 65 || event.keyCode === 67 || event.keyCode === 86 || event.keyCode === 88) && (event.ctrlKey === true || event.metaKey === true)) ||
                        // Allow: .
                        (event.keyCode === 190 || event.keyCode === 110) ||
                        // 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();
                        }
                    }
                });
            }
        }

I tried to add '$(element).val().indexOf('.') !== -1' like below but it does not do anything and I can still type in as many periods I want. 我试图添加'$(element).val().indexOf('.') !== -1'如下所示,但是它什么也没做,我仍然可以输入任意多个周期。 How should I actually restrict it? 我实际上应该如何限制它?

if (event.shiftKey || ($(element).val().indexOf('.') !== -1 && (event.keyCode === 190 || event.keyCode === 110)) || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                event.preventDefault();
                        }

So I must say I don't really see the logic in allowing explicitly; 所以我必须说,我没有真正看到明确允许的逻辑。 instead you should exclude explicitly as by default everything is allowed. 相反,您应该明确地排除在外,因为默认情况下允许所有操作。 You buy a computer after it having passed all your criteria, you don't buy 10 computers, then throw away those that don't fit your criteria. 您在满足所有条件后购买了计算机,没有购买10台计算机,然后丢弃了不符合条件的计算机。 So, no need to touch the Ctrl & other function keys, you're making it needlessly complicated. 因此,无需触摸Ctrl和其他功能键,就可以使它变得不必要地复杂。
If you look carefully at your extremely long if clause, you will notice the following: 如果仔细看一下您的long if子句,您会注意到以下内容:
(event.keyCode === 190 under which you stated // let it happen, don't do anything . So periods will always be added regardless. Here are the gotchas with your current approach: (event.keyCode === 190 ,您在其中声明// let it happen, don't do anything 。因此// let it happen, don't do anything将始终添加句点。这是当前方法的陷阱:

  • with the keydown event, all keycodes produce the same value with Caps Lock on or not, because they're the same keys . 使用keydown事件时,无论是否启用Caps Lock键,所有键码都会产生相同的 ,因为它们是相同的 So you cannot distinguish between period . 因此,您无法区分句点. and semicolon ; 和分号; .
  • with the keydown event, keycodes for the same number on a numpad and on the keyboard are different , because they are different keys . 对于keydown事件,数字键盘和键盘上相同数字的键码是不同的 ,因为它们是不同的
  • Disabling the Shift key (like you did), forces AZERTY users to use Caps Lock because AZERTY keyboards produce the non-numerical char when Shift is off. 禁用Shift键(就像您一样),会强制AZERTY用户使用Caps Lock,因为在Shift关闭时,AZERTY键盘会生成非数字字符。

As a result you are much better off using the keypress event, which returns the character value . 因此,使用keypress事件(返回字符值)会更好。 Here is a refactored and much more concise function, that achieves exactly the same: 这是一个重构的且更简洁的功能,其功能完全相同:

 $('#jquery').on("keypress", function (event) {
   var k = event.keyCode || event.charCode;
   if (k === 46 && this.value.match(/\./g) || (k < 48 && k !== 46 ) || k > 57) {                            
     event.preventDefault();
   }
 });

Test it here: http://jsfiddle.net/kevinvanlierde/5ay3cory/6/ 在此处进行测试: http : //jsfiddle.net/kevinvanlierde/5ay3cory/6/

NOTE: Because Mozilla Firefox sucks at making the difference between keydown and keypress, it messes up and disables all control keys too. 注意:由于Mozilla Firefox吸引了按键和按键之间的区别,因此它会混乱并禁用所有控制键。

if ((yourString.match(new RegExp(".", "g")) || []).length > 1) {
  // yourString contains more than one "."
}

I fixed my own code and thought I'd share it here: 我修复了自己的代码,并想在这里共享它:

// Allows only numbers with decimals
$(element).on("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 || event.metaKey === true)) ||
        // Allow: .
        (event.keyCode === 190 || event.keyCode === 110) ||
        // Allow: home, end, left, right
        (event.keyCode >= 35 && event.keyCode <= 39)) {
        // let it happen, but check for excessive periods
        if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
            event.preventDefault();
        }
        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();
        }
    }
});

I added the following code where it allows certain keycodes: 我在允许某些键码的位置添加了以下代码:

if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
    event.preventDefault();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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