Input OTP

Input OTP components allow users to enter a one-time password by typing one character per input field in a series.

Examples

This section demonstrates various ways to use the Input OTP component, including different layouts and customization options.

Basic 6-digit OTP with divider

This example shows a standard 6-digit OTP input split into two groups of three, separated by a dash. Each input accepts a single digit, and users can paste the entire code for convenience.

-
<div class="otp-wrapper">
<div class="input-group otp-group">
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>

<span class="dash mx-2">-</span>

<div class="input-group otp-group">
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>

6-digit OTP without divider

This example displays a continuous 6-digit OTP input without any visual divider. All six input fields are grouped together, suitable for codes that do not require separation.

<div class="otp-wrapper">
<div class="input-group otp-group">
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>

6-digit OTP with two dividers

This example demonstrates a 6-digit OTP input split into three groups of two, each group separated by a dash. This layout is useful for codes formatted as XX-XX-XX.

-
-
<div class="otp-wrapper">
<div class="input-group otp-group">
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>

<span class="dash mx-2">-</span>

<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>

<span class="dash mx-2">-</span>

<div class="input-group otp-group">
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
  <input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>

OTP input with helper text

This example combines the OTP input with a helper text below, guiding users to enter their one-time password. This is helpful for accessibility and clarity.

Enter your one-time password.

<div class="d-flex flex-column align-items-center">
  <div class="otp-wrapper mb-2">
      <div class="input-group otp-group">
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
          <input type="text" maxlength="1" class="form-control otp-input text-center" />
      </div>
  </div>
  <p class="text-body mb-0">Enter your one-time password.</p>
</div>

Complete OTP form with label and submit button

This example presents a full OTP input form, including a label, helper text, and a submit button. It demonstrates how to integrate the OTP input into a typical authentication flow.

Please enter the one-time password sent to your phone.

Your one-time password must be 6 characters.
<form class="otp-validate-form" novalidate>
  <label for="otp-group" class="form-label">One-Time Password</label>
  <div class="otp-wrapper mb-2">
      <div class="input-group otp-group">
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
          <input type="text" maxlength="1" class="form-control otp-input text-center" required />
      </div>
  </div>
  <p class="text-muted mb-1">Please enter the one-time password sent to your phone.</p>
  <div class="otp-error-message text-danger mb-3 d-none">
    Your one-time password must be 6 characters.
  </div>
  <button class="btn btn-primary" type="submit">Submit</button>
</form>
document.addEventListener('DOMContentLoaded', function () {
  const form = document.querySelector('.otp-validate-form');
  const inputs = form.querySelectorAll('.otp-input');
  const label = form.querySelector('.form-label');
  const errorMessage = form.querySelector('.otp-error-message');

  form.addEventListener('submit', function (e) {
    e.preventDefault(); // prevent submission

    // Convert NodeList to Array for easier handling
    const inputArray = Array.from(inputs);

    // Count filled inputs
    const filledInputs = inputArray.filter(input => input.value.trim() !== '');

    if (filledInputs.length < 6) {
      // Show error message
      errorMessage.classList.remove('d-none');

      // Make label red
      label.classList.add('text-danger');

      // Focus the first empty input
      const firstEmpty = inputArray.find(input => input.value.trim() === '');
      if (firstEmpty) firstEmpty.focus();
    } else {
      // All inputs filled — proceed
      errorMessage.classList.add('d-none');
      label.classList.remove('text-danger');

      form.submit();
    }
  });

});
On this page
Quick Links
Admin
Admin Dashboard Example

Themes

Other