मैं उपयोगकर्ता को कई स्टाइल देने के लिए एक टेक्स्ट इनपुट दिखाकर एक संख्यात्मक इनपुट मास्क/मूल्य जोड़ी बना रहा हूं (यानी हजारों को अल्पविराम से विभाजित करना), और वास्तविक मूल्य को एक छिपे हुए नंबर इनपुट में फ़ॉर्म में भेजने के लिए संग्रहीत करना।
अभी मैं देख रहा हूं कि दृश्यमान इनपुट के मान को संपादित करने से चयन सूचकांक बहुत अंत तक अपडेट हो जाता है, जो कि जब आप इनपुट को मान के बीच में। मैं समझता हूं कि स्थिति खो गई है क्योंकि मूल्य पूरी तरह से फिर से लिखा जा रहा है, लेकिन मैं इसे वापस अपडेट करने के लिए मैन्युअल रूप से इसका ट्रैक कैसे रख सकता हूं, यह देखते हुए कि 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>
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;
});