make an input only-numeric type on knockout

后端 未结 10 909
情书的邮戳
情书的邮戳 2020-11-30 06:15

i read many tutorials but i dont know how to do this, this is the input

input(type=\"text\",name=\"price\",id=\"price\"data-bind=\"text: price,valueUpdate:[\         


        
相关标签:
10条回答
  • 2020-11-30 06:36

    Knockout has extenders for this. Check This from knockoutjs.com explaining how to use observable extenders to force input to be numeric. I paste the code from the documentation here:

    Source code: View

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

    Source code: View model

    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));
    
    0 讨论(0)
  • 2020-11-30 06:38
     <input type="text" id="alpha-validation" data-bind="value: YourDataName, valueUpdate: 'afterkeydown' , event: { 'input': AlphaCheck}" style="text-transform:uppercase">
    

    create AlphaCheck Function and add that.

        $('#alpha-validation').keyup(function () {
            if (this.value.match(/[^0-9 ]/g)) {
                this.value = this.value.replace(/[^0-9 ]/g, '');
            }
        });
    

    That will works!

    0 讨论(0)
  • 2020-11-30 06:43

    An alternative approach: I have found that Knockout works well in combination with jQuery-validate. You just need to make sure that you validate the form before you attempt to use the numeric value.

    Say you have a form DOM element, you can set up validation rules via

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

    In your viewmodel you set the two-way binding up as usual, e.g. via self.year = ko.observable(""). Now make sure that you call $(".yourform").valid() before you are further processing self.year(). In my case, I am doing var year = parseInt(self.year(), 10). Right after form validation this is expected to always produce a meaningful result.

    0 讨论(0)
  • 2020-11-30 06:45

    We can restrict user to input user more than two decimal number Ex. 23.81, 3452.83 Modified code is as below. The reference code is taken from the @Martin Surynek answer.

    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 -

    <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>
    
    0 讨论(0)
提交回复
热议问题