How do I stop my activeElement.value modifications from modifying the activeElement and the following element?

28 views Asked by At

I am creating a set of input boxes that accept 1 character each.

Whenever I keydown a character, I want the document.activeElement.value to be set to the value of the event.key and then I want to focus() on the next input box.

Similarly, whenever I press the backspace or delete, I want the value of the activeElement to be set to "" and I was to focus() on the previous or next input as appropriate.

This is somewhat working, but the inputs are being applied to the activeElement at the time of the keydown AND the next activeElement that is focused on after the focus() code has been run.

Here are a few snippets of what I have tried so far:

In this block, the code is meant to clear the value of the active input box and backspace focus to the previous input box. Instead, it's clearing the value of the activeElement, back-spacing focus to the previous input box, and then clearing the previous box's value as well.

element.addEventListener('keydown', function(event) {
        if (event.key == "Backspace"){
            console.log("backspaced");
            if (document.activeElement.id == "1"){
                console.log("cannot return any further");
            }
            document.activeElement.value = '';
            let index = (parseInt(document.activeElement.id)) - 1;
            document.getElementById(index).focus();
        }

and

In this block, the code is meant to apply the value of the event.key to the activeElement and then move focus to the next input box. Instead, it's applying the value of the event.key to the activeElement, moving focus to the next input box, and then changing the new activeElement's value as well.

if (event.key.length == 1 || (event.key.length > 1 && /[^a-zA-Z0-9]/.test(event.key))){
            console.log("something was pressed");
            if (document.activeElement.id == "9"){
                console.log("password complete");
            }
            document.activeElement.value = event.key;
            let index = (parseInt(document.activeElement.id)) + 1;
            document.getElementById(index).focus();
        }

I suspect the code changing the value of the activeElement is still running after the focus has been changed, but I am not sure how to stop this without totally changing my code. Any ideas?

1

There are 1 answers

0
Yosef Tukachinsky On

You can preventDefault for the event and manage the input value yourself. here is a working example:

function handleInputChange(event) {
  event.preventDefault();
  const input = event.target;
  const index = +input.id.substring(1);

  if(/^[a-zA-Z0-9]$/.test(event.key)) {
    input.value = event.key;
    if(index < 5) document.querySelector(`#i${index+1}`).focus();
  }
  else if(event.code === 'Backspace') {
    input.value = '';
    if(index > 1) document.querySelector(`#i${index - 1}`).focus();
  }
}
#container {
  display: flex;
  gap: 6px;
}

input {
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  border: 1px solid #c1c1c1;
  text-align: center;
}
<div id="container">
<input id="i1" onkeydown="handleInputChange(event)"/>
<input id="i2" onkeydown="handleInputChange(event)"/>
<input id="i3" onkeydown="handleInputChange(event)"/>
<input id="i4" onkeydown="handleInputChange(event)"/>
<input id="i5" onkeydown="handleInputChange(event)"/>
<div>