简体   繁体   English

KnockoutJs 将输入标签绑定到用逗号格式化数字

[英]KnockoutJs binding for input tag to format number with comma

Is there available binding to format an input value from 123456789 to 123,456,789 .是否有可用的绑定来格式化从123456789123,456,789的输入值。 The binding should work on every keypress and validate the value if it is a valid number.绑定应该适用于每个按键并验证该值是否为有效数字。 I found this solution but it is not formatting on keypress.我找到了这个解决方案,但它不是在按键上格式化。

I ended up creating custom binding.我最终创建了自定义绑定。 It only works on IE10 and above for the usage of event input .它只适用于 IE10 及以上的event input的使用。 Here's the code.这是代码。 See fiddle here .请参阅此处的小提琴。

String.prototype.countOccurence = function(char){
  return (this).split(char).length - 1;
}

$.fn.selectRange = function(start, end){
  if(end === undefined)
    end = start;
  return this.each(function() {
    if("selectionStart" in this){
      this.selectionStart = start;
      this.selectionEnd = end;
    } else if(this.setSelectionRange)
      this.setSelectionRange(start, end);
    else if(this.createTextRange){
      var range = this.createTextRange();
      range.collapse(true);
      range.moveEnd("character", end);
      range.moveStart("character", start);
      range.select();
    }
  });
};

ko.helper = {};

ko.helper['toNumber'] = function (value, limit){
    limit = limit || 10;
    var num = Number((value || "").toString().replace(/[^0-9]/gi, "").substring(0, limit));
    return num;
}

ko.bindingHandlers['formatNumber'] = {
    init: function(element, valueAccessor, allBindings){
        var value = valueAccessor();
        var limit = allBindings.get("limit") || 10; //billion
        var position = 0;
        var navigationKeys = [33, 34, 35, 36, 37, 38, 39, 40, 9];
        var isBackSpace = false;
        var oldLengthValue = (value() || "").toString().length;

        function isKeyControls(e){
                    if(e.ctrlKey && (e.keyCode == 67 || e.keyCode == 86 || e.keyCode == 65)){
                        return true;
                    }
                    if(e.shiftKey && (e.keyCode == 37 || e.keyCode == 39)){
                        return true;
                    }

                    return false;
                }

        $(element).on("keyup", function(e) {
                    if(this.selectionStart == this.value.length)
                        return;

                    if(isKeyControls(e) || e.shiftKey){
                        return;
                    }

                    var navigation = (e.keyCode == 37
                                          ? -1
                                          : e.keyCode == 39
                                                ? 1
                                                : 0);
                    var customSelectionStart = this.selectionStart; // + navigation;
                    //customSelectionStart = customSelectionStart
                    var positionMinusOne = customSelectionStart == 0
                                               ? -1
                                               : customSelectionStart;

                    positionMinusOne = positionMinusOne + (positionMinusOne == -1 ? 0 : navigation);
                    var previousCharacter = positionMinusOne == -1
                                                ? ""
                                                : this.value.substring(customSelectionStart - 1, customSelectionStart);

                    if(previousCharacter == ","){
                        $(this).selectRange(customSelectionStart +
                        (isBackSpace ? -1 : 0));
                    }

                    var currentCommaOccurence = this.value.countOccurence(",");
                    var commaValue = oldLengthValue > currentCommaOccurence ? -1
                                         : oldLengthValue < currentCommaOccurence ? 1
                                               : 0;
                    if(commaValue != 0){
                        $(this).selectRange(customSelectionStart +
                            commaValue);
                    }

                    oldLengthValue = this.value.countOccurence(",");
                });

        $(element).on("keydown", function (e) {
                    if (isKeyControls(e)) {
                        return;
                    }

                    var navigation = (e.keyCode == 37
                                          ? -1
                                          : e.keyCode == 39
                                                ? 1
                                                : 0);
                    var customSelectionStart = this.selectionStart + navigation;
                    //customSelectionStart = customSelectionStart
                    var positionMinusOne = customSelectionStart == 0
                                               ? -1
                                               : customSelectionStart;

                    positionMinusOne = positionMinusOne + (positionMinusOne == -1 ? 0 : navigation);
                    var previousCharacter = positionMinusOne == -1
                                                ? ""
                                                : this.value.substring(customSelectionStart - 1, customSelectionStart);

                    if(previousCharacter == ",")
                        $(this).selectRange(customSelectionStart);

                    isBackSpace = e.keyCode == 8;
                    if(isBackSpace)
                        return;

                    //Navigation
                    if(navigationKeys.some(function(key) {
                        return key == e.keyCode;
                    }))
                        return;

                    //Other Keys
                    var isNumber = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105);
                    var isLimit = (limit + parseInt(limit / 3)) == this.value.length;
                    if(!(isNumber)
                        || isLimit){
                        e.preventDefault();
                        return;
                    }
                });

        $(element).on("input", function(e, a, b, c) {
                    console.log(this.selectionStart, this.selectionEnd);
                    var convertedValue = ko.helper.toNumber(this.value, limit);
                    var formatted = convertedValue
                                        ? ko.helper.toNumber(this.value, limit).toLocaleString()
                                        : "";
                    position = this.selectionStart == this.value.length
                                   ? formatted.length
                                   : this.selectionStart;
                    value(convertedValue || "");
                    this.value = formatted;
                    $(this).selectRange(position);
                });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                    $(element).off();
                });

        ko.bindingHandlers["formatNumber"].update(element, valueAccessor, allBindings);
    },
    update: function(element, valueAccessor, allBindings){
        var value = valueAccessor();
        var limit = allBindings.get("limit") || 10; //billion                
        var convertedValue = ko.helper.toNumber(value(), limit);
        var formatted = convertedValue
                            ? ko.helper.toNumber(value(), limit).toLocaleString()
                            : "";
        element.value = formatted;
    }
};

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

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