Javascript 在敲除时仅输入数字类型

Javascript 在敲除时仅输入数字类型,javascript,knockout.js,knockout-2.0,Javascript,Knockout.js,Knockout 2.0,我读了很多教程,但我不知道怎么做,这是输入 input(type="text",name="price",id="price"data-bind="text: price,valueUpdate:['afterkeydown','propertychange','input']") 这是我的viewModel price: ko.computed(function() { return parseFloat(this.replace(' ','').replace(/[^0-9\.]+

我读了很多教程,但我不知道怎么做,这是输入

input(type="text",name="price",id="price"data-bind="text: price,valueUpdate:['afterkeydown','propertychange','input']")
这是我的viewModel

price: ko.computed(function()
{
    return parseFloat(this.replace(' ','').replace(/[^0-9\.]+/g,"")) || '';
},this)

但这会导致错误:这有没有办法取代???如何将价格值传递给计算函数???

最好创建只接受允许的字符[0-9,.]作为数字表示的自定义绑定

把这条线放到你的视野里

<input id="text" type="text" data-bind="numeric, value: number">

将这一行放入模型中(记住将数字绑定为可观察属性)

ko.bindingHandlers.numeric={
init:函数(元素、值访问器){
$(元素).on(“向下键”),函数(事件){
//允许:退格、删除、制表符、转义和回车
如果(event.keyCode==46 | | | event.keyCode==8 | | event.keyCode==9 | | event.keyCode==27 | | event.keyCode==13||
//允许:Ctrl+A
(event.keyCode==65&&event.ctrlKey==true)||
//允许:,
(event.keyCode==188 | | event.keyCode==190 | | event.keyCode==110)||
//允许:起始、结束、左、右

(event.keyCode>=35&&event.keyCode另一种方法:我发现Knockout与结合使用效果很好。您只需确保在尝试使用数值之前验证表单

假设您有一个表单DOM元素,您可以通过

$(".yourform").validate({
    rules: {
        year: {
            digits: true,
            minlength: 4,
            maxlength: 4
        }
    },
    messages: {
        year: "Please enter four digits (e.g. 2009).",
    }
});

在viewmodel中,您像往常一样设置双向绑定,例如通过
self.year=ko.observable(“”
)。现在确保在进一步处理
self.year()
之前调用
$(“.yourform”).valid()
。在我的情况下,我正在执行
var year=parseInt(self.year(),10)
。表单验证之后,这将始终产生有意义的结果。

Knockout为此提供了扩展程序。来自knockoutjs.com,解释如何使用可观察扩展程序强制输入为数字。我将文档中的代码粘贴到此处:

源代码:查看

<p><input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p><input data-bind="value: myNumberTwo" /> (round to two decimals)</p>

那就行了!

我知道这个问题已经有一年了,但是为了页面的功能访问者,让我发布这个问题

看看这个:

ko.bindingHandlers.numericnumbers = {
init: function (element) {
    $(element).on('keypress', function (number) {
        number = (number) ? number : window.event;
        var charcode = (number.which) ? number.which : number.keyCode;
        if (charcode > 31 && (charcode < 48 || charcode > 75))
            number.preventDefault();
    });
}};
ko.bindingHandlers.numericnumbers={
init:函数(元素){
$(元素).on('keypress',函数(数字){
编号=(编号)?编号:window.event;
var charcode=(number.which)?number.which:number.keyCode;
如果(字符码>31&(字符码<48 | |字符码>75))
number.preventDefault();
});
}};

创建指向新代码的数据绑定:

<input id="price" name="price" type="text" data-bind="numeric">
这意味着每次更新价格时,它都会应用函数中的逻辑(在本例中,去掉任何不是数字或周期的内容),并将其直接应用于价格。您还可以在此处添加其他验证或酷功能,如在开始处添加货币sybmol,将其保留在小数点后2位等。

借助“按键”事件,我们可以限制文本框中应包含数值的其他键

$(document).ready(function(){                
        $("selector").on("keydown", function (e) {
            //numbers, delete, backspace, arrows
            var validKeyCodes = [8, 9, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
            if (!($.inArray(e.keyCode, validKeyCodes) >= 0))
                    e.preventDefault();                 
        });           
    });

我们可以限制用户输入两个以上的十进制数,例如23.81、3452.83修改代码如下。参考代码取自@Martin Surynek答案

HTML-

<p>
    <input data-bind="value: myNumberOne" /> (round to whole number)</p>
  <p>
    <input data-bind="num, value: myNumberTwo" /> (round to two decimals)</p>

(四舍五入至整数)

(四舍五入至小数点后两位)

剧本-

<script>
    ko.bindingHandlers.num = {
      init: function (element, valueAccessor) {
        $(element).on("keypress", function (event) {
          //debugger
          console.log(event.keyCode);
          var $this = $(this);
          var text = $this.val();

          // Stop insert two dots
          if ($this.val().indexOf('.') != -1 && (event.which == 190 || event.which == 110)) {
            event.preventDefault();
          }

          // 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) ||
            // Allow: .   ,event.keyCode == 188 ||
            ( 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;
          }

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

          if ((event.which == 46) && (text.indexOf('.') == -1)) {
            setTimeout(function () {
              if ($this.val().substring($this.val().indexOf('.')).length > 3) {
                $this.val($this.val().substring(0, $this.val().indexOf('.') + 3));
              }
            }, 1);
          }

          if ((text.indexOf('.') != -1) &&
            (text.substring(text.indexOf('.')).length > 2) &&
            (event.which != 0 && event.which != 8) &&
            ($(this)[0].selectionStart >= text.length - 2)) {
            event.preventDefault();
          }          
          //console.log($(this)[0].selectionStart >= text.length - 2);
        });
      }
    };


    ko.extenders.numeric = function (target, precision) {
      //create a writable computed observable to intercept writes to our observable

      var result = ko.pureComputed({
        read: target, //always return the original observables value
        write: function (newValue) {

          var current = target(),
            roundingMultiplier = Math.pow(10, precision),
            newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
            valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

          //only write if it changed
          if (valueToWrite !== current) {
            target(valueToWrite);
          } else {
            //if the rounded value is the same, but a different value was written, force a notification for the current field
            if (newValue !== current) {
              target.notifySubscribers(valueToWrite);
            }
          }
        }
      }).extend({
        notify: 'always'
      });

      //initialize with current value to make sure it is rounded appropriately
      result(target());

      //return the new computed observable
      return result;
    };

    function AppViewModel(one, two) {
      this.myNumberOne = ko.observable(one).extend({
        numeric: 0
      });
      this.myNumberTwo = ko.observable(two).extend({
        numeric: 2
      });
    }

    ko.applyBindings(new AppViewModel(221.2234, 123.4525));
  </script>

ko.bindingHandlers.num={
init:函数(元素、值访问器){
$(元素).on(“按键”,函数(事件){
//调试器
console.log(event.keyCode);
var$this=$(this);
var text=$this.val();
//停止插入两个点
if($this.val().indexOf('.')!=-1&&(event.which==190 | | event.which==110)){
event.preventDefault();
}
//允许:退格、删除、制表符、转义和回车
如果(event.keyCode==46 | | event.keyCode==8 | | event.keyCode==9 | | event.keyCode==27 | | event.keyCode==
13 ||
//允许:Ctrl+A
(event.keyCode==65&&event.ctrlKey==true)||
//允许:,event.keyCode==188||
(event.keyCode==190 | | event.keyCode==110)||
//允许:起始、结束、左、右

(event.keyCode>=35&&event.keyCode我也有类似的问题

我还需要只确保inter值,对于IE9及以上(因此type=numberical是不够的),而且由于我们有很多国际客户,我也不能依赖keycodes,因此我最终得出以下结论:

//In my js class method (self is this as usual)
self.ensureNumberical = function (data, e) {
    var keyValue = e.key;
    if (keyValue.match(/[0-9]/g)) {
        return true;
    }
    return false;
}

//In my MVC View
data-bind="event: { keypress: ensureNumberical }"

最适合今天的场景

运行下面的代码段。输入非数字或大于255的内容将显示该消息

函数模型(){
var self=这个;
this.myObj=ko.observable().extend({digit:true}).extend({max:255});
}
var mymodel=新模型();
$(文档).ready(函数(){
ko.validation.init();
ko.应用绑定(mymodel);
});

输入一个小于或等于255的数字

输入数字以外的内容或超过255将导致错误。

如果您将其更改为
input type=“number”
,而不是
input type=“text”
,会怎么样?我认为这些限制了您输入的内容仅限于数值。type=“number”与某些浏览器的兼容性较低Jon是正确的,您可以将类型更改为数字,但如果我没记错的话,并不是所有浏览器都支持该类型。例如,我相信IE10之前的任何内容都可以让您毫无问题地在其中输入文本这可以用来查看兼容性在knockout的文档中有一个关于此的主题。Yo你可能需要创建一个扩展器。他们的示例实际上满足了你的要求。这真的有效吗?对我来说,如果它在UI上的某个位置,它不会更新Observable?例如,你有如上所述,还有一些。在这种情况下,如果用户编辑输入中的数字,则在编辑完成后UI不会更新。更改w
price = ko.observable();
price.subscribe(function(newValue) {
    price = newValue.replace(/[\D\.]/g, '');
});
$(document).ready(function(){                
        $("selector").on("keydown", function (e) {
            //numbers, delete, backspace, arrows
            var validKeyCodes = [8, 9, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
            if (!($.inArray(e.keyCode, validKeyCodes) >= 0))
                    e.preventDefault();                 
        });           
    });
<p>
    <input data-bind="value: myNumberOne" /> (round to whole number)</p>
  <p>
    <input data-bind="num, value: myNumberTwo" /> (round to two decimals)</p>
<script>
    ko.bindingHandlers.num = {
      init: function (element, valueAccessor) {
        $(element).on("keypress", function (event) {
          //debugger
          console.log(event.keyCode);
          var $this = $(this);
          var text = $this.val();

          // Stop insert two dots
          if ($this.val().indexOf('.') != -1 && (event.which == 190 || event.which == 110)) {
            event.preventDefault();
          }

          // 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) ||
            // Allow: .   ,event.keyCode == 188 ||
            ( 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;
          }

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

          if ((event.which == 46) && (text.indexOf('.') == -1)) {
            setTimeout(function () {
              if ($this.val().substring($this.val().indexOf('.')).length > 3) {
                $this.val($this.val().substring(0, $this.val().indexOf('.') + 3));
              }
            }, 1);
          }

          if ((text.indexOf('.') != -1) &&
            (text.substring(text.indexOf('.')).length > 2) &&
            (event.which != 0 && event.which != 8) &&
            ($(this)[0].selectionStart >= text.length - 2)) {
            event.preventDefault();
          }          
          //console.log($(this)[0].selectionStart >= text.length - 2);
        });
      }
    };


    ko.extenders.numeric = function (target, precision) {
      //create a writable computed observable to intercept writes to our observable

      var result = ko.pureComputed({
        read: target, //always return the original observables value
        write: function (newValue) {

          var current = target(),
            roundingMultiplier = Math.pow(10, precision),
            newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
            valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;

          //only write if it changed
          if (valueToWrite !== current) {
            target(valueToWrite);
          } else {
            //if the rounded value is the same, but a different value was written, force a notification for the current field
            if (newValue !== current) {
              target.notifySubscribers(valueToWrite);
            }
          }
        }
      }).extend({
        notify: 'always'
      });

      //initialize with current value to make sure it is rounded appropriately
      result(target());

      //return the new computed observable
      return result;
    };

    function AppViewModel(one, two) {
      this.myNumberOne = ko.observable(one).extend({
        numeric: 0
      });
      this.myNumberTwo = ko.observable(two).extend({
        numeric: 2
      });
    }

    ko.applyBindings(new AppViewModel(221.2234, 123.4525));
  </script>
//In my js class method (self is this as usual)
self.ensureNumberical = function (data, e) {
    var keyValue = e.key;
    if (keyValue.match(/[0-9]/g)) {
        return true;
    }
    return false;
}

//In my MVC View
data-bind="event: { keypress: ensureNumberical }"