I want to add spaces in a card ID input field automatically as the user is typing it. Here is my setup:
<input placeholder="e.g. 5200 1234 5678 9012 3456" bind:value={inputAC}
on:keydown={inputACKeydown}>
let inputAC = ""
function inputACKeydown(e: KeyboardEvent) {
// Add spaces to the input
if (e.key !== "Backspace" && e.key !== "Delete" && inputAC.length % 5 === 4) {
inputAC += " "
}
}
However, the on:keydown event seems to be called before reactivity happens, which means that the inputAC value when the event calls are still the old value, not the new value. So spaces will only be added when the user enters the 5th character, not when the user finishes entering the 4th character.
You can put the contents of the handler in a setTimeout(() => { ... });
block to make it run after the event's effects have taken place.
Another approach would be to remove the bind:
, handle input
instead of keydown
, deal with the various kinds of inputType
yourself and prevent the event's default. E.g. if the inputType
is 'insertText'
, the added text can be read from the data
property and added to the state variable. This is rather complicated though.
Also, the current mechanism does not prevent unintended groupings if the space is deleted and other text is inserted instead. There probably needs to be some normalization that is applied on the whole string or at least earlier input.