我正在创建数字输入掩码/值对,方法是向用户显示一个文本输入以给它提供几种样式(即用逗号分隔数千个),然后将要发送给表单的实数值存储在一个隐藏数字中输入。
现在,我注意到编辑可见输入的值会将选择索引更新到最后,这在您从the middle of the value编辑输入时是不直观的。我了解到,自从位置值被完全重写以来,该位置已经丢失,但是鉴于on.('input')
事件处理程序会在该值已经更改后触发,因此如何手动跟踪以更新该位置keydown
事件是在修改发生之前发生的吗?
$("#foo").on('change paste input mouseup', function() {
const validation_decimals = 3 //allowed decimal places
const $mask = $('#foo')
const $value = $('#baz')
let hasDot = $mask.val().includes('.')
let nValue = $mask.val().replace(/[a-zA-Z]/g, "").replace(/[!¡@#$%^&\/+*()=¿?":;\[\]\-_~`\\{}'|<>]/g, "")
// only one period allowed
if (hasDot) {
if ($mask.val().match(/\./g).length > 1) {
let newVal = $mask.val()
const lastDot = newVal.lastIndexOf('.')
newVal = newVal.slice(0, lastDot) + newVal.slice(lastDot + 1)
$mask.val(newVal)
}
}
$value.val(parseFloat($mask.val().replace(/,/g, "")))
// adding comma-based thousands grouping
let [integers, decimals] = $value.val().toString().split('.')
if (integers.length > 3) {
for (let iReverse = -3; iReverse > -integers.length; iReverse -= 4) {
integers = integers.slice(0, iReverse) + ',' + integers.slice(iReverse)
}
}
let fValue = integers
if (hasDot) {
fValue += '.'
}
if (decimals !== undefined) {
fValue += decimals
}
$('#foo').val(fValue)
})
// preventing more decimal places than allowed and user-inputted commas.
$("#foo").on('select click keydown', function(e) {
let selStart = e.target.selectionStart;
let selEnd = e.target.selectionEnd;
const isComma = e.keyCode == 188
const isNumber = (e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105)
const validation_decimals = 3
if ($(this).val().includes('.')) {
const value = $(this).val()
const decimals = value.split('.')[value.split('.').length - 1]
const decimalLengthReached = decimals.length == validation_decimals
const selectionBeforePeriod = selStart < value.indexOf('.') || selEnd > selStart
if (isNumber && decimalLengthReached && !selectionBeforePeriod) {
e.preventDefault()
}
}
if (isComma) {
e.preventDefault()
}
})
.input-group {
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='form-group'>
<label for='foo'>User Field (type here)</label>
<div class="input-group mb-3">
<input type="text" class="form-control" id='foo' step='0.01' aria-label="Amount (to the nearest dollar)">
</div>
<label for='baz'><em>Hidden field</em></label>
<div class="input-group mb-3">
<input type="number" id='baz' aria-label="Amount (to the nearest dollar)" step='0.1'>
</div>
</div>
答案 0 :(得分:1)
在完全重写输入字段之前,可以使用输入字段的selectionStart
属性确定插入符号的位置。
document.querySelector("#my-input").addEventListener("change", function() {
// Get the position of the caret before you rewrite the input field
let caretPosition = document.querySelector("#my-input").selectionStart;
// Rewrite the input field here
// Put the caret back to where it was
document.querySelector("#my-input").selectionStart = caretPosition;
});