Reputation: 343
I have multiple inputs which allow a single digit numeric value. The script below confirms the the value is a number.
How can I move focus to the next input when a valid number has been input?
<input type="text" maxlength="1" onkeypress="return isNumber(event)" required>
function isNumber(evt) {
evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if (charCode > 31 && (charCode < 49 || charCode > 53)) {
return false;
}
return true;
}
Upvotes: 3
Views: 4407
Reputation:
You can find the next element by using Node.nextElementSibling
then assign focus using HTMLElement.focus()
To make it iterate to the next row, you have to check whether currently focused element is the last element in the current row. If so then move to the next line.
It is better to use Event.preventDefault()
in the Element.onkeydown
property and then check to see if the element has been filled in the Element.onkeyup
property as the keypress
event is fired both when the key is pressed down and again when it is released.
var validChar;
var inputs = document.querySelectorAll('td input[type=text]'), i;
for(i = inputs.length - 1; i >= 0; i--) {
inputs[i].onkeydown = checkNumber;
inputs[i].onkeyup = checkFilled;
}
function checkNumber(event) {
event = (event) ? event : window.event;
var charCode = (event.which) ? event.which : event.keyCode;
if (!(charCode >= 48 && charCode <= 53)
&& !(charCode >= 96 && charCode <= 101)
&& !(charCode == 16 || charCode == 9)) {
event.preventDefault();
return false;
} else if(!(charCode == 16 || charCode == 9)) {
validChar = true;
}
}
function checkFilled(event) {
if(validChar && event.target.value.length === 1) {
validChar = false;
nextInput(event.target.parentNode);
}
}
function nextInput(el) {
if(el.nextElementSibling) {
if(!el.nextElementSibling.firstElementChild) {
nextInput(el.nextElementSibling);
return false;
}
var nextSibling = el.nextElementSibling.firstElementChild;
} else {
if(!el.parentNode.nextElementSibling) {
return false;
}
var nextRow = el.parentNode.nextElementSibling;
if(!nextRow.firstElementChild.firstElementChild) {
nextInput(nextRow.firstElementChild);
return false;
}
var nextSibling = nextRow.firstElementChild.firstElementChild;
}
var nextType = nextSibling.tagName.toLowerCase();
if(nextType !== "input") {
nextInput(nextSibling);
return false;
}
nextSibling.focus();
}
<table>
<tr>
<td>some text</td>
<td>some text</td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
</tr>
<tr>
<td>some text</td>
<td>some text</td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
<td><input type="text" maxlength="1" required></td>
</tr>
</table>
Upvotes: 4
Reputation: 8945
In this case, I suggest that you expand the definition of what's now being called an isNumber()
function. Pass a second parameter to it, giving the ID of the control that should be moved-to if the input is a number. Then, in that subroutine, quash the event and then setFocus
to the proper "next control." Each onkeypress
handler would call the same routine, but with a different next-control-id parameter, so that each control sends us on to the proper next-one.
I would counsel you: don't try to simulate pressing the Tab key.
Upvotes: 0