I have a form in Vue that has some combined inputs for styling reasons for a phone number input.
My problem is that the user has to hit tab in order to go to the next input field of the phone number.
Is there a way to check for the max length of the current and input and when that is met go to the next input?
<div class="combined-input combined-input--phone" :class="{'error--input': phoneInvalid('patientInformation')}"> <div class="open-parenthesis"></div> <input type="text" id="phoneArea" maxlength="3" @blur="$v.formData.patientInformation.phone.$touch()" v-model.trim="$v.formData.patientInformation.phone.area.$model"> <div class="close-parenthesis"></div> <input type="text" id="phoneA" maxlength="3" @blur="$v.formData.patientInformation.phone.$touch()" v-model.trim="$v.formData.patientInformation.phone.a.$model"> <div class="dash"></div> <input type="text" id="phoneB" maxlength="4" @blur="$v.formData.patientInformation.phone.$touch()" v-model.trim="$v.formData.patientInformation.phone.b.$model"> </div>
Advertisement
Answer
Pretty sure this is not recommended UX-wise but here is an example on how you can achieve it: https://codesandbox.io/s/move-to-next-input-on-condition-103b5?file=/src/App.vue
The main part of useful code is
focusNextOncePopulated(event, max) { if (event.target.value.length === max) { const nextElement = this.$refs?.[`input-${Number(event.target.dataset.index) +1}`] if (nextElement) nextElement.focus() } },
Explanation: each time you input a char, you check if the length of the field reached the maximum you’ve set on a particular input. If it is and there is a similar input as a sibling, you focus it.
Adding a debounce
of a few milliseconds would be nice too, performance-wise.
EDIT: to prevent any issues of trying to find the correct next input
in the DOM, we setup some refs on each of the inputs (recommended way in Vue to select some DOM elements). Then, when we have reached the max
, we increment our current’s input data-index
by one, which enables us to go to the next input.
PS: ?.
syntax is optional chaining, it prevents ugly code and allows to avoid an error if there is no next input
once max
is reached.
PS: Not sure if there is a way to directly get the $refs
of an element on it’s @input
event but if there is, I didn’t found out how to do it.