Input OTP
An input for one-time passwords and verification codes, rendered as individual character slots
<dui-input-otp max-length="6"/>Usage
The dui-input-otp Tag Helper renders a segmented input for one-time passwords and verification codes. It is backed by a single hidden <input> that holds the whole code — so it model-binds and posts back like any other text field — overlaid on the individual character slots. A small del-input-otp web component distributes what you type into the slots, moves the active slot and caret, and enforces the allowed character pattern.
Use the max-length attribute to control how many characters the code has.
<dui-input-otp max-length="6"/>Input OTP only submits a value when you set asp-for or name. Just like a
native input without a name, an Input OTP without one (such as most of the
examples on this page) renders and is fully interactive but posts nothing. Use
asp-for to model bind, or set name to post a value
without binding.
Examples
Number of digits
Use the max-length attribute to set the number of slots. It defaults to 6.
<dui-input-otp max-length="4"/>Groups
Use the groups attribute to split the slots into groups, separated by a separator. Provide a comma-separated list of group sizes — the sizes must add up to max-length (when both are set), otherwise the total is taken from the groups.
<dui-input-otp groups="3,3"/>Separator
A separator is rendered automatically between groups. Supply more than two groups to add multiple separators.
<dui-input-otp groups="2,2,2"/>Pattern
Use the pattern attribute to constrain the allowed characters with a regular expression — any input that would make the value fail to match is rejected. It defaults to digits only (^\d*$). Pair it with inputmode to control the on-screen keyboard.
<dui-input-otp max-length="6" pattern="^[a-zA-Z0-9]*$" inputmode="text"/>Composition
For full control over the layout, compose the slots by hand with the dui-input-otp-group, dui-input-otp-slot, and dui-input-otp-separator Tag Helpers instead of letting groups generate them. Slots take their position automatically in document order.
<dui-input-otp max-length="6">
<dui-input-otp-group>
<dui-input-otp-slot/>
<dui-input-otp-slot/>
<dui-input-otp-slot/>
</dui-input-otp-group>
<dui-input-otp-separator/>
<dui-input-otp-group>
<dui-input-otp-slot/>
<dui-input-otp-slot/>
<dui-input-otp-slot/>
</dui-input-otp-group>
</dui-input-otp>Model binding
The dui-input-otp Tag Helper has full support for ASP.NET Core model binding using the asp-for attribute. Bind it to a string and the whole code posts straight back to the property.
When using model binding, DuneUI will automatically wrap the input inside a Field with the correct label and description derived from data attributes. You can opt out of this behavior by setting the render-field attribute to false.
<dui-input-otp asp-for="OneTimePassword" groups="3,3"/>public class ModelBindingModel
{
[Display(
Name = "One-time password",
Description = "Enter the 6-digit code we sent to your phone."
)]
public string OneTimePassword { get; set; } = "123";
}Validation
Validation works like any other model-bound field. Add validation attributes to your model and the slots reflect the invalid state, with the error message rendered below.
<dui-input-otp asp-for="OneTimePassword" groups="3,3"/>public class ValidationModel
{
[Display(
Name = "One-time password",
Description = "Enter the 6-digit code we sent to your phone."
)]
[Required(ErrorMessage = "Enter the complete 6-digit code")]
[StringLength(6, MinimumLength = 6, ErrorMessage = "Enter the complete 6-digit code")]
public string OneTimePassword { get; set; } = "123";
}Manual Validation
If you're not using ASP.NET Core model binding, you can manually indicate validation errors by setting the aria-invalid attribute to true. This applies the destructive styling to the slots.
The error message can be displayed using either a dui-field-error Tag Helper (when using explicit fields) or the error attribute (when using implicit fields).
<dui-field>
<dui-label>One-time password</dui-label>
<dui-input-otp aria-invalid="true" groups="3,3"/>
<dui-field-error>Enter the complete 6-digit code</dui-field-error>
<dui-field-description>
Enter the 6-digit code we sent to your phone.
</dui-field-description>
</dui-field><dui-input-otp
label="One-time password"
description="Enter the 6-digit code we sent to your phone."
error="Enter the complete 6-digit code"
aria-invalid="true"
groups="3,3"/>Disabled
Add the disabled attribute to prevent the user from interacting with the input.
<dui-input-otp max-length="6" value="123" disabled="true"/>