Dynamically shift HTML input focus to the next element

A guide on how to dynamically move the focus on HTML input elements if when first is filled in. This requires a little bit of JavaScript.

a bored fish

Introduction

A certain banking app that I am familiar with requires the user to insert numbers from their personal 6-figure secret number. When the user inserts to the first input field, the focus automatically shifts to the next input field. I wanted to know how this is achieved. Below is my solution to the problem.

Demonstration of the dynamic focus result

Below are 4 number inputs. Type a number into the first and you will notice that as soon as you do the focus shifts to the next input. There is no change on the last one.

Cool hey? So how is this achieved?

HTML number input

You will see that the first element has autofocus. This focus is intially applied when the page loads. Each element has been given a class of input. These will be used in the JavaScript.

<div class='inputDemo'>
 <input type='number' class='input' id='0' autofocus />
 <input type='number' class='input' id='1' />
 <input type='number' class='input' id='2' />
 <input type='number' class='input' id='3' />
</div>

You will notice I have provided a stringified numerical id for each input. These will be used by the JavaScript too.

Styling the HTML input with CSS

The following CSS styling is straightforward.

input[type='number'] {
 width: 40px;
 height: 40px;
 padding: 12px;
 margin: 4px;
}

A :focus is then applied to add a background colour when the input is in focus.

input[type='number']:focus {
 background-color: #e6e6e6;
}

Remove the default arrows on number inputs

This following snippet cancels the default arrows or chevrons on HTML number input elements.

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
 -webkit-appearance: none;
 margin: 0;
}

The JavaScript logic for dynamic input focus

First we need to ‘hook up’ each input to an event listener that will respond when an imput is made.

The inputs variable is a node list that can be looped through. Here it is iterated with forEach and an eventListener is added to each element.

const inputs = document.querySelectorAll('.input');

inputs.forEach((el) => {
  el.addEventListener('input', checker);
});

Now, when the user makes an input, the checker function is called. The function takes in the argument e, or event. The variable named next takes the id of the current input, converts it to a number, using +, and adds one. This represents the id of the next input field in the row, used in the focusThis variable.

function checker(e) {
 let next = +e.target.id + 1;
 let focusThis = document.getElementById(`${next}`);
 if (focusThis && e.target.value.length === 1) {
  if (focusThis.value === '') {
   focusThis.focus();
  } else {
  return;
  }
 }
}

The logic in the if statement checks that focusThis exists AND that the current input value is a single figure. If both these are truthy, the next input is checked for an empty value. If this is also truthy, the focus is added to the next input. If any of the if statements are falsy, nothing happens.

That’s it. I hope this helps.

Thank you for stumbling across this website and for reading my blog post entitled Dynamically shift HTML input focus to the next element