gpt4 book ai didi

javascript - 在格式化数字后将插入符设置回原来的位置

转载 作者:行者123 更新时间:2023-11-30 15:00:54 24 4
gpt4 key购买 nike

我有一个输入字段,它有一个数据操作并且是一个小数字段。一切正常,除了当我输入超过 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);
<!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>

最佳答案

最简单的做法是取消 valueUpdate 设置,以便在用户编辑完数字后进行格式化。

要让它以交互方式工作,您需要添加一个input 事件处理程序

  1. 找出光标后面有多少位数字(这发生在重新格式化之前)
  2. 执行setTimeout 以允许重新格式化
  3. 在相同位数后设置光标位置

另请注意,对于非常长的数字,您的格式化程序会变得很奇怪。您可能希望将其替换为对 toLocaleString 的调用加上一些额外的替换。

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);
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown', event: {input: findPlace}" type="text" />

关于javascript - 在格式化数字后将插入符设置回原来的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46549030/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com