Reputation: 581
How do you auto focus the next input field?
When all the input fields are placed one after the other like this
<div>
<input type="number" name="name">
<input type="number" name="name">
<input type="number" name="name">
</div>
you can generally just do something like this
this.nextSibling.nextSibling.focus();
However, I have a situation where there is a variable number of <span>
tags between each input field.
Something like
<div>
<input type="number" name="name">
<span></span>
<span></span>
<span></span>
<span></span>
<input type="number" name="name">
<span></span>
<input type="number" name="name">
<span></span>
<span></span>
<input type="number" name="name">
</div>
How do I configure
this.nextSibling.nextSibling.focus();
to get to the next input sibling?
Upvotes: 0
Views: 3721
Reputation: 36594
You can create a variable and to keep track of current input. And each time increase it. And focus the next input from array of inputs.Below is the code
let inputs = document.querySelectorAll('input');
let i = 0;
inputs.forEach(inp => inp.oninput = () => inputs[i+1] && inputs[++i].focus())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input type="number" name="name">
<span></span>
<input type="number" name="name">
<span></span>
<input type="number" name="name">
<span></span>
<span></span>
<input type="number" name="name">
</div>
Upvotes: 1
Reputation: 11
There is a rather simple solution. Use id attribute on the input elements. Then you can automatically move to the next element with a simple switch within your validation function.
Such as:
function validateInput(input){
//Your validation code
switch(input.id){
case'input1':
document.getElementById('input2').focus();
break;
case'input2':
document.getElementById('input3').focus();
break;
case'input3':
document.getElementById('input4').focus();
break;
}
}
<input type='number' name='name' id='input1' onchange='validateInput(this)'>
<input type='number' name='name' id='input2' onchange='validateInput(this)'>
Then you don't have to worry about where in the document it is, you can always find it. You could even do your validation from within the switch or send it to an external function and continue within validateInput with a non-null return
Upvotes: 1
Reputation: 371168
You could just keep looping through the nextElementSibling
s until you find one that matches the tagName
you're looking for:
document.querySelectorAll('input').forEach((input) => {
input.oninput = function() {
let { nextElementSibling } = this;
while (nextElementSibling && nextElementSibling.tagName !== 'INPUT') {
nextElementSibling = nextElementSibling.nextElementSibling;
}
if (nextElementSibling) {
nextElementSibling.focus();
}
}
});
<div>
<input type="number" name="name">
<span></span>
<span></span>
<span></span>
<span></span>
<input type="number" name="name">
<span></span>
<input type="number" name="name">
<span></span>
<span></span>
<input type="number" name="name">
</div>
If you want to specify something more specific than a tagName
, you can use Element.prototype.matches
:
document.querySelectorAll('input').forEach((input) => {
input.oninput = function() {
let { nextElementSibling } = this;
while (nextElementSibling && !nextElementSibling.matches('input[name="foo"]')) {
nextElementSibling = nextElementSibling.nextElementSibling;
}
if (nextElementSibling) {
nextElementSibling.focus();
}
}
});
<div>
<input type="number" name="name">
<span></span>
<span></span>
<span></span>
<span></span>
<input type="number" name="foo">
<span></span>
<input type="number" name="name">
<span></span>
<span></span>
<input type="number" name="foo">
</div>
Note the use of nextElementSibling
rather than nextSibling
- nextSibling
will select adjacent nodes, not just Elements. (for example, nextSibling
can evaluate to a text node, which you don't care about.) If you want an element, best to be specific and use nextElementSibling
.
Upvotes: 3
Reputation: 510
<div>
<input type="number" tabindex="1" name="name">
<span></span>
<span></span>
<span></span>
<span></span>
<input type="number" tabindex="2" name="name">
<span></span>
<input type="number" tabindex="3" name="name">
<span></span>
<span></span>
<input type="number" tabindex="4" name="name">
</div>
I am using tabindex
in this example because your question doesn't provide any insight as to why I can't use it.
Upvotes: 1