Have you ever found it frustrating to enter a phone number split across multiple input fields? Manually tapping to move from one field to the next can disrupt the flow and slow you down. A smoother experience is to have the cursor automatically jump to the next field — saving time and making form filling feel seamless.
This small UX improvement can make a big difference, especially on mobile devices where precise tapping is harder. In this tutorial, I’ll show you how to implement automatic field transitions for phone number inputs using jQuery.
HTML Structure
1
2
3
4
5
6
7
8
9
10
| <div class="phone_form">
<h2>Phone Number</h2>
<div class="input_container">
<input type="tel" id="phone1" maxlength="3" class="phone_input" placeholder="123" inputmode="numeric" pattern="[0-9]*" aria-label="Area code">
<span class="separator" aria-hidden="true">-</span>
<input type="tel" id="phone2" maxlength="4" class="phone_input" placeholder="4567" inputmode="numeric" pattern="[0-9]*" aria-label="First part of phone number">
<span class="separator" aria-hidden="true">-</span>
<input type="tel" id="phone3" maxlength="4" class="phone_input" placeholder="8901" inputmode="numeric" pattern="[0-9]*" aria-label="Last part of phone number">
</div>
</div>
|
Input Fields
The type="tel"
attribute brings up the numeric keypad on mobile. maxlength
limits input length, while placeholders help guide the user.
Accessibility Enhancements
Each input has an aria-label
so screen reader users understand its purpose. Separators are marked with aria-hidden="true"
so they’re ignored by assistive tech.
Input Optimization
Combining inputmode="numeric"
with pattern="[0-9]*"
helps ensure numeric-only input and improves the mobile experience.
CSS Styling
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| .phone_form {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
background-color: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.phone_form h2 {
color: #333;
margin-bottom: 10px;
}
.input_container {
display: flex;
align-items: center;
gap: 8px;
}
.phone_input {
width: 100px;
height: 50px;
border: 1px solid #ddd;
border-radius: 6px;
text-align: center;
font-size: 18px;
padding: 0 5px;
transition: all 0.2s ease;
}
.phone_input:focus {
border-color: #8ab4f8;
outline: none;
box-shadow: 0 0 0 2px rgba(78, 67, 118, 0.2);
}
.separator {
font-size: 20px;
color: #666;
margin: 0 2px;
}
|
Layout and Visuals
The form uses flex layout with clean spacing and a soft shadow for a polished look.
Input Field Design
Fields are large, centered, and easy to read. Focus state includes a color change and glow for better usability.
Separator Styling
The dashes between fields are styled for visibility but excluded from screen readers.
jQuery Code – Auto Focus Behavior
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| function inputFocus(){
// Select all phone input fields
const $phoneInputs = $('.phone_input');
// Function to move between fields (direction: 1=next, -1=previous)
function moveField($currentField, direction) {
const currentIndex = $phoneInputs.index($currentField);
const targetIndex = currentIndex + direction;
// Only move within valid index range
if(targetIndex >= 0 && targetIndex < $phoneInputs.length) {
$phoneInputs.eq(targetIndex).focus();
}
}
// Handle input changes
$phoneInputs.on('input', function() {
// Filter to allow numbers only
this.value = this.value.replace(/[^0-9]/g, '');
// Auto-move to next field when max length is reached
if (this.value.length === this.maxLength) {
moveField($(this), 1);
}
});
// Keyboard event handling (details below)
$phoneInputs.on('keydown', function(e) {
// Detailed code explained in the next section
});
}
$(function(){
inputFocus();
})
|
Auto-Tab Logic
The moveField
function calculates where the cursor should go based on the current input’s index.
Input Validation + Auto Advance
On every input, non-numeric characters are stripped out. If the input reaches its maximum length, focus jumps to the next field.
Optional: Keyboard Navigation Enhancements
To take it a step further, let’s add some intuitive keyboard controls:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| $phoneInputs.on('keydown', function(e) {
const key = e.key || e.keyCode;
const $this = $(this);
// Move to previous field on Backspace if field is empty
if ((key === 'Backspace' || key === 8) && this.value.length === 0) {
e.preventDefault();
moveField($this, -1);
}
// Right Arrow to next field if cursor is at the end
else if ((key === 'ArrowRight' || key === 39) && this.selectionStart === this.value.length) {
e.preventDefault();
moveField($this, 1);
}
// Left Arrow to previous field if cursor is at the start
else if ((key === 'ArrowLeft' || key === 37) && this.selectionStart === 0) {
e.preventDefault();
moveField($this, -1);
}
});
|
Backspace Navigation
Hitting Backspace on an empty field takes you back to the previous one—super handy for quick corrections.
Arrow Key Support
Arrow right at the end of a field moves forward, and arrow left at the beginning moves back.
Cursor Detection
We use selectionStart
to detect cursor position, ensuring we don’t interfere with normal editing.
💡 Pro Tip: Supporting both key
and keyCode
makes your code more robust across browsers, including legacy ones.
Conclusion
This jQuery-powered auto-tab solution makes phone number entry faster and more user-friendly—especially on mobile. It’s a lightweight enhancement that improves form UX with just a few lines of code.
You can apply the same logic to other types of segmented inputs too—credit card numbers, SSNs, PIN codes, and more.
Have you tried something like this before? Or have a UX annoyance you want to fix? Let’s chat in the comments! 😊