KnockoutJS截取到小数点后一位 [英] KnockoutJS intercept to one decimal place

查看:95
本文介绍了KnockoutJS截取到小数点后一位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有人问过这种变化,但我的要求是,除了格式化/舍入输入的值外,我什至不允许用户在小数点后输入多个数字.我有一些可与decimalFormatter绑定处理程序一起使用的东西,但它很笨拙-即,它允许您输入类似"20"的值.而且由于我编写正则表达式的方式,您无法删除所有值.我意识到我可以修改它以接受整个条目的可选数字,但是我真正想要的是如果用户删除该值,它将还原为0.0.并且,允许他们输入"20".然后跳出(onblur),并将其重新格式化为20.0,以使其看起来更完整.当前,如果用户输入"20".然后保存该表单,它确实存储了整个值20,并且当您从数据库中重新打开/检索该值时,它显示为20.0,因此重新加载时看起来还不错.

I know variations of this have been asked, but my requirement is that instead of formatting/rounding the value that's entered, I need to not even allow the user to enter more than one number after the decimal point. I have something that works with a decimalFormatter binding handler, but it's clunky - i.e., it allows you to enter a value like '20.' and you can't erase all the values due to the way I have the regular expression written. I realize I could modify that to accept optional digits for the whole entry, but what I really want is for it to revert to 0.0 if the user erases the value. And, allow for them to enter '20.' then tab out (onblur) and have it reformat the value to 20.0 so it looks more complete. Currently, if the user enters '20.' then saves the form, it does store a whole value of 20, and when you reopen/retrieve the value from the database, it shows 20.0 so it looks fine when reloading.

我曾考虑添加一个onblur事件,但是我们不想这样做,因为它会覆盖掉除掉的数据绑定.我们想让所有东西都受ko视图模型的约束,所以这不是一个选择.我也看到有人建议计算得出的可观察值(例如,这样的 post ),但是我的绑定已经做到了.再三考虑,敲除事件绑定是这里的方法吗???

I thought about adding an onblur event but we don't want to do that in overriding what has been databound by knockout. We want to keep everything bound by the ko view model, so that's not an option. I've also seen some suggest a computed observable (for example this SO post) but my binding already does that. On second thought, would the knockout event binding be the way to go here???

html:

<input style="width:38px" data-bind="decimalFormatter: percentage"/>

javascript:

javascript:

ko.bindingHandlers.decimalFormatter = {
    init: function (element, valueAccessor) {
    var initialValue;

    //$(element).on('keydown', function (event) {
    $(element).keydown(function (event) {
        initialValue = $(element).val();

        // 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 combinations
        (event.ctrlKey === true) ||
        // Allow decimal/period
        (event.keyCode === 110) || (event.keyCode === 190) ||
        // 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();
            }
        }
    });

    $(element).keyup(function (event) {
        if (!$(element).val().match(/^\d+\.?\d?$/)) {
            event.preventDefault();
            $(element).val(initialValue);
        }
        else
            return;
    });        

    var observable = valueAccessor();

    var interceptor = ko.computed({
        read: function () { return formatWithComma(observable(), 1); },
        write: function (newValue) {
            observable(reverseFormat(newValue, 1));
        }
    });

    if (element.tagName == 'INPUT')
        ko.applyBindingsToNode(element, { value: interceptor });
    else
        ko.applyBindingsToNode(element, { text: interceptor });
    },
    update: function (element, valueAccessor) {
    }
}

// Formatting Functions
function formatWithComma(x, precision, seperator) {
    var options = {
        precision: precision || 2,
        seperator: seperator || '.'
    }
    var formatted = parseFloat(x, 10).toFixed(options.precision);
    var regex = new RegExp('^(\\d+)[^\\d](\\d{' + options.precision + '})$');
    formatted = formatted.replace(regex, '$1' + options.seperator + '$2');
    return formatted;
}

function reverseFormat(x, precision, seperator) {
    var options = {
        precision: precision || 2,
        seperator: seperator || '.'
    }

    var regex = new RegExp('^(\\d+)[^\\d](\\d+)$');
    var formatted = x.replace(regex, '$1.$2');
    return parseFloat(formatted);
}

var viewModel = function () {
    var self = this;
    self.percentage = ko.observable(20.0);
};

var vm = new viewModel();
ko.applyBindings(vm);

JSFiddle

推荐答案

好吧,我使用AUTONUMERIC插件进行数字格式化,这是可靠而又棒的.

Well i used AUTONUMERIC plugin for number formatting which was reliable and awesome .

我只是根据您的要求制作了一个样本提琴,请检查 此处

I just made a sample fiddle to your requirement check it here

查看模型:

var vm = function(){   
this.Amount=ko.observable(""); 
this.OnloadAmount=ko.observable(143); //onLoad Test
ko.bindingHandlers.autoNumeric = {
       init: function (el, valueAccessor, bindingsAccessor, viewModel) {
            var $el = $(el),
              bindings = bindingsAccessor(),
              settings = bindings.settings,
              value = valueAccessor();

            $el.autoNumeric(settings);
            $el.autoNumeric('set', parseFloat(ko.utils.unwrapObservable(value()), 10));
            $el.change(function () {
                value(parseFloat($el.autoNumeric('get'), 10));
            });
        },
        update: function (el, valueAccessor, bindingsAccessor, viewModel) {
            var $el = $(el),
              newValue = ko.utils.unwrapObservable(valueAccessor()),
              elementValue = $el.autoNumeric('get'),
              valueHasChanged = (newValue != elementValue);

            if ((newValue === 0) && (elementValue !== 0) && (elementValue !== "0")) {
                valueHasChanged = true;
            }

            if (valueHasChanged) {
                $el.autoNumeric('set', newValue);
            }
        }
    };
}

  ko.applyBindings(new vm());

查看:

<input type="text"  data-bind="autoNumeric:$data.Amount, settings:{mDec:1,aSep: ''} " />

此处mDec:1将数字限制为1的十进制位置,而asep:''表示不会用逗号等分隔数字

Here mDec:1 restricts number to decimal palce of one and asep:'' means it will not sperate number with commas etc

PS::我们可以限制输入无效字符并轻松进行其他操作.

PS: we can restrict entering invalid characters and do lots of other stuff with ease .

有关完整的参考,请参见 此处

For complete Reference check here

这篇关于KnockoutJS截取到小数点后一位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆