我知道有人提出了这方面的变化,但我的要求是,不需要格式化/舍入输入的值,我甚至不允许用户在小数点后输入多个数字.我有一些适用于decimalFormatter绑定处理程序的东西,但它很笨重 – 也就是说,它允许你输入像’20’这样的值.并且由于我编写正则表达式的方式,您无法擦除所有值.我意识到我可以修改它以接受整个条目的可选数字,但我真正想要的是,如果用户删除该值,它将恢复为0.0.并且,允许他们进入’20’.然后选项卡(onblur)并将其重新格式化为20.0,使其看起来更完整.目前,如果用户输入’20’.然后保存表单,它确实存储整数值20,当你重新打开/检索数据库中的值时,它显示20.0,所以它在重新加载时看起来很好.
我想过添加一个onblur事件,但是我们不想在覆盖被淘汰的数据绑定时做到这一点.我们希望保持ko视图模型的所有约束,因此这不是一个选项.我也看到一些建议计算的observable(例如这个SO post)但我的绑定已经做到了.在第二个想法,淘汰赛event binding将成为这里的方式???
HTML:
<input style="width:38px" data-bind="decimalFormatter: percentage"/>
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,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插件进行数字格式化,这是可靠和令人敬畏的.
我只是根据你的要求做了一个小样,检查它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,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的十进制数:”表示它不会用逗号等来编号
PS:我们可以限制输入无效字符并轻松完成许多其他操作.
完整参考检查here