我有一个输入字段,它有一个数据操作并且是一个十进制字段。一切正常,但是当我输入3个以上的数字时,由于字段格式化,它会丢失当前的插入符并将其设置为字段的末尾。 例: 123工作正常 1234将导致1'234.00并且插入符号位于最后0之后。如何将插入符号设置回其原始位置? (在4和之间。)
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
&#13;
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
</head>
<body>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown'" type="text" />
</body>
</html>
&#13;
答案 0 :(得分:2)
最简单的做法是摆脱valueUpdate
设置,以便在用户完成编辑后完成格式化。
要让它以交互方式工作,您需要添加一个<{1}}事件处理程序
input
是否允许重新格式化另请注意,对于非常长的数字,格式化程序会变得奇怪。您可能希望将其替换为toLocaleString
,并进行一些额外的替换。
setTimeout
&#13;
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
self.findPlace = function (data, event) {
const pos = event.target.selectionEnd;
var numbersBeforePos = event.target.value.substr(0, pos).replace(/\D/g, '').length;
setTimeout(function() {
const formattedValue = event.target.value;
const numbersNow = event.target.value.replace(/\D/g, '').length;
if (numbersNow >= numbersBeforePos) {
// find the numbersBeforePos-th number
const re = /\d/g;
var newPos;
while (numbersBeforePos--) {
newPos = 1 + re.exec(formattedValue).index;
}
event.target.setSelectionRange(newPos, newPos);
}
}, 0);
};
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
&#13;