繁体   English   中英

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

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

是否有可用的绑定来格式化从123456789123,456,789的输入值。 绑定应该适用于每个按键并验证该值是否为有效数字。 我找到了这个解决方案,但它不是在按键上格式化。

我最终创建了自定义绑定。 它只适用于 IE10 及以上的event input的使用。 这是代码。 请参阅此处的小提琴。

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