How do you automatically change focus to the next input box after user enters the maximum character length by setting the tab index
Hm Iād rather not go with those solutions TBH⦠theyāre all suggesting to listen to key events, which would also prevent you from using tab, shift and arrow keys once the max length is reached⦠not to mention theyāre hard-coding the max lengths in the JS, rather than setting the actual maxlength
attribute. Using jQuery, of course.
So hereās a simple generic solution, that also should not conflict with keyboard navigation:
<input type="text" maxlength="3" class="auto-focus-next">
<input type="text" maxlength="5" class="auto-focus-next">
<input type="text" maxlength="2" class="auto-focus-next">
function initAutoFocus (input, index, list) {
const next = list[index + 1]
if (!next) {
return
}
input.addEventListener('input', () => {
if (input.value.length === input.maxLength) {
next.focus()
}
})
}
document
.querySelectorAll('.auto-focus-next')
.forEach(initAutoFocus)
So what would be the CSS properties to go with the class, auto-focus-next
There is no CSS required here, the purpose of those classes is merely to apply the behaviour in the JS. If it should apply to all input elements with a max length, you might as well use that for the selector though:
document
.querySelectorAll('[maxlength]')
.forEach(initAutoFocus)
Hereās a pen:
Ok. Thanks
Can you resize this input box?
Thanks
Sure.
Can you show me how to change the properties on this input box, I canāt get it to change from the default long rectangular box. I applied height and width.
Thanks
Now this is just CSS really:
CSS
.small-input {
width: 42px;
}
HTML
<input class="small-input">
What if each of the input boxes in post#4 had a letter in it and it was supposed to spell a word, if right display a checkmark and a message, say ābedā if wrong display a āxā; how would I do that?
Thanks
Does that mean that you expect each of the input boxes from Post #4 to have a maxlength of one character each, instead of having different maxlengths of 3, 5, and 2?
In that case, youāll want an input event that gets the values from each input box, and when all of them are filled in it shows either a or a
Hereās the code that achieves that.
function documentInputHandler(evt) {
const fields = document.querySelectorAll('.auto-focus-next');
const values = Array.from(fields).map(f => f.value).filter(v => v);
if (values.length < fields.length) {
return;
}
document.querySelector("#result").innerHTML = (
values.join("") === "bed" ? "ā
" : "ā"
);
}
document.addEventListener("input", documentInputHandler);
You can see the code working at https://jsfiddle.net/kp43f5yL/
Yes, each input box will have a wavelength of 1,but there will be more results than ābedā
Sorry maxlength
If you just want to check if each input is filled, you can add a required
attribute:
<input maxlength="1" required class="auto-focus-next">
This will show an error message for missing values when you try to submit the form, but you can also customise how to report that error using CSS and / or JS:
Right now it seems that weāre trying to build a platypus from descriptions of different types of creatures.
It would be really helpful to get a full description of what is wanted.
Well I was just reading all the different codes, havenāt tried them yet, but as for a description, what I have is three input boxes ābedā, as in post #12 to validate when the user enters data;it will either be right or wrong (check, if right or x if wrong). If check,there will be a message displayed .There will be more input words to validate besides ābedā.
In your post#13ā¦values.joinā¦===bed
Do you need this statement for each word? Hope this makes senseš
Three input boxes each with a letter in it, a sample word of ābedā which is three letters, so one letter per box, which is why the auto-advance to the next box.
Each box contains no more than a single letter. That is the shape of my elephant.
Going with @Paul_Wilkinsā solution you might define a list of valid words, and check if the joined values are in that list:
const WORDS = ['foo', 'bar', 'baz']
// ...
document.querySelector('#result').innerHTML = (
WORDS.includes(values.join('')) ? 'ā
' : 'ā'
)
Another possibility would be to define a pattern on a parent fieldset as a data attribute, mimicking the pattern
constraint validtation so that you donāt have to maintain a hard-coded list of valid words in your JS:
CSS
.error {
display: none;
}
.invalid {
border: 1px solid red;
}
.invalid .error {
display: block;
}
HTML
<fieldset data-pattern="foo|bar|baz">
<input type="text" maxlength="1" class="auto-focus-next">
<input type="text" maxlength="1" class="auto-focus-next">
<input type="text" maxlength="1" class="auto-focus-next">
<p class="error">pattern mismatch</p>
</fieldset>
JS
function validatePattern (event) {
const fieldset = event.currentTarget
const pattern = new RegExp(fieldset.dataset.pattern)
const value = Array.from(
fieldset.elements,
element => element.value
).join('')
fieldset.classList.toggle(
'invalid',
!pattern.test(value)
)
}
document
.querySelectorAll('[data-pattern]')
.forEach(element => {
element.addEventListener('change', validatePattern)
})
Thanks