There's an input field, when the user will type any fullwidth Japanese character (numbers only) it won't be displayed on that input field. It'll be converted to its respective halfwidth character and, then that halfwidth character will be visible inside that same input field.
If user type 0, this 0 will not be shown in the input field, it'll show the converted halfwidth 0. In my case the problem is if the user types 0, the function is running twice and showing 00, but it should be only 0. Can anybody please help me to sort it out?
<input type="text" id="inputField" oninput="convertToHalfWidth(this.value)">
<script>
function convertToHalfWidth(input) {
console.log(input);
// Map of full-width to half-width numbers
const fullToHalfMap = {
'0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9'
};
// Replacing full-width numbers with their half-width counterparts
const convertedInput = input.replace(/[0-9]/g, match => fullToHalfMap[match]);
// Updating the input field with the converted value
document.getElementById('inputField').value = convertedInput;
}
</script>
As per spec:
The start of a composition is marked by dispatching a compositionstart event. During a composition session, whenever a text composition system updates its active text passage, a compositionupdate event is dispatched. After each compositionupdate event, a pair of beforeinput and input events are dispatched.
The problem is an input event with type insertCompositionText is fired whenever an a composition session is updated. Even for simple full width characters like numbers and space that doesn't require multiple symbols composed using an IME window, there will still be two input event fired by compositionupdate. (Reproduced on Chinese IME and Japanese full-width Katakana IME.)
Note that this problem won't be reproduced by pasting the full characters because there won't be any composition session started. Only an input event with type insertText will be started.
One solution is to use an additional compositionend event to handle composition input types. (Or a simple onkeyup is enough if you are okay with the delay between keydown and keyup.)
const inputField = document.getElementById('inputField');
const fullToHalfMap = {
'0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9'
};
inputField.addEventListener('input', function (e) {
// Might be enough to only check insertFromPaste inputType
if (e.inputType !== 'insertCompositionText') {
convertToHalfWidth(e);
}
})
inputField.addEventListener('compositionend', convertToHalfWidth);
function convertToHalfWidth(e) {
const input = e.target.value;
// Replacing full-width numbers with their half-width counterparts
const convertedInput = input.replace(/[0-9]/g, match => fullToHalfMap[match]);
// Updating the input field with the converted value
inputField.value = convertedInput;
}
<input type="text" id="inputField">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With