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

查看:24
本文介绍了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 视图模型的约束,所以这不是一个选项.我也看到一些建议计算 observable(例如这个 SO 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天全站免登陆