feat: OTP inputs auto-advance to next field when digit is typed
- oninput moves focus to next field when digit entered - onkeydown Backspace moves to previous field when current is empty - Last field (digit_5) only handles backspace
This commit is contained in:
parent
7ab94a14d0
commit
4ea3d63b29
1 changed files with 13 additions and 7 deletions
|
|
@ -49,24 +49,30 @@ func loadTemplates() {
|
||||||
log.Printf("Loaded %d templates", len(templates))
|
log.Printf("Loaded %d templates", len(templates))
|
||||||
}
|
}
|
||||||
|
|
||||||
// otpFormHTML is the inline OTP form template fragment.
|
// otpFormHTML is the inline OTP form template fragment with auto-advance.
|
||||||
const otpFormHTML = `
|
const otpFormHTML = `
|
||||||
<form hx-post="/verify-otp" hx-target="#otp-form" hx-swap="innerHTML">
|
<form hx-post="/verify-otp" hx-target="#otp-form" hx-swap="innerHTML">
|
||||||
<input type="hidden" name="email" value="{{.Email}}">
|
<input type="hidden" name="email" value="{{.Email}}">
|
||||||
{{if .Error}}<div class="error-message" style="color: #fca5a5; background: #450a0a; border: 1px solid #7f1d1d; padding: 0.75rem; border-radius: 0.5rem; margin-bottom: 1rem;">{{.Error}}</div>{{end}}
|
{{if .Error}}<div class="error-message" style="color: #fca5a5; background: #450a0a; border: 1px solid #7f1d1d; padding: 0.75rem; border-radius: 0.5rem; margin-bottom: 1rem;">{{.Error}}</div>{{end}}
|
||||||
<div style="display: flex; gap: 0.5rem; justify-content: center; margin: 1rem 0;">
|
<div style="display: flex; gap: 0.5rem; justify-content: center; margin: 1rem 0;">
|
||||||
<input type="text" name="digit_0" maxlength="1" pattern="[0-9]" inputmode="numeric" autocomplete="one-time-code" required
|
<input type="text" name="digit_0" maxlength="1" pattern="[0-9]" inputmode="numeric" autocomplete="one-time-code" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
oninput="if(this.value)this.nextElementSibling.focus()" onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
<input type="text" name="digit_1" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
<input type="text" name="digit_1" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
oninput="if(this.value)this.nextElementSibling.focus()" onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
<input type="text" name="digit_2" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
<input type="text" name="digit_2" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
oninput="if(this.value)this.nextElementSibling.focus()" onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
<input type="text" name="digit_3" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
<input type="text" name="digit_3" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
oninput="if(this.value)this.nextElementSibling.focus()" onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
<input type="text" name="digit_4" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
<input type="text" name="digit_4" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
oninput="if(this.value)this.nextElementSibling.focus()" onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
<input type="text" name="digit_5" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
<input type="text" name="digit_5" maxlength="1" pattern="[0-9]" inputmode="numeric" required
|
||||||
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;">
|
style="width: 3rem; height: 3rem; text-align: center; font-size: 1.5rem; border: 2px solid #475569; border-radius: 0.5rem; background: #1e293b; color: #f8fafc;"
|
||||||
|
onkeydown="if(event.key==='Backspace'&&!this.value)this.previousElementSibling?.focus()">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary btn-block">Verify Code</button>
|
<button type="submit" class="btn btn-primary btn-block">Verify Code</button>
|
||||||
</form>`
|
</form>`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue