I would change the event to keydown
instead of keyup
, as keyup
will already have processed the tab event itself, and there is no real cancelling you could do at that time (you will visually see it jump to the next field, before the next empty code has been selected)
For the rest, I would suggest you get all the elements first, and then check which field had the event triggered, and start checking the other fields from index + 1
So in large, I guess I would code something like the following ( no need to blur
the field you are currently on, focus
on the new field would do)
There is a handle for shiftKey
so that users can still use shift+tab to go one back :) (I commented in the link from where that check came from)
let itemInputs = Array.from( document.querySelectorAll('.item-input') );
$('.item-input').on('keydown', function( e ) {
if (e.shiftKey) {
// no handling here
// see: https://stackoverflow.com/questions/3044083/what-is-the-key-code-for-shifttab
return;
}
switch (e.keyCode) {
case 9:
// we could have the loop in here, but hey, default returns out of the function
// so this just skips till behind the switch statement
break;
default:
return;
}
// find where we are in the original fieldset
let index = itemInputs.findIndex( v => e.target === v ) + 1;
// if we are equal or larger then itemInputs
while (index < itemInputs.length) {
if (itemInputs[index].value.length === 0) {
// prevent the default step
e.preventDefault();
itemInputs[index].focus();
return;
}
// try next
index++;
}
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
<div class="field">
<span class="label">Text 1</span>
<span class="value"><input type="text" value="" class="item-input" /></span>
</div>
<div class="field">
<span class="label">Text 2</span>
<span class="value"><input type="text" value="Skip me" class="item-input" /></span>
</div>
<div class="field">
<span class="label">Text 3</span>
<span class="value"><input type="text" value="" class="item-input" /></span>
</div>
<div class="field">
<span class="label">Text 4</span>
<span class="value"><input type="text" value="" class="item-input" /></span>
</div>
</fieldset>