advanced forms
Tailwind CSS Pin Input
The Pin Input component enables quick entry for scenarios such as multi-factor authentication, offering features like regex validation and clipboard pasting.
Basic pin input example.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item autofocus />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
</div>
Pin input with placeholder.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
Default pin input example.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
Apply the pin-input-underline
class to change the pin input style to an underline.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
</div>
Add responsive class pin-input-{size}
where {size} = xs|sm|md|lg|xl
for pin input of different sizes.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xs" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-sm" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-lg" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-xl" placeholder="○" data-pin-input-item />
</div>
Underline pin input sizes example.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xs" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xs" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-sm" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-sm" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-lg" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-lg" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input pin-input-underline pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xl" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input pin-input-underline pin-input-xl" placeholder="○" data-pin-input-item />
</div>
To disable pointer events and prevent focusing, add the disabled
boolean attribute to an input.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item disabled />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item disabled />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item disabled />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item disabled />
</div>
Control the number of pin input as per you preference.
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
<div class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
By default, this accepts both letters and numbers. To restrict input to numbers/letters only, set "availableCharsRE"
to "^[a-z]+$"
/ "^[0-9]+$"
.
<div class="flex space-x-3" data-pin-input='{"availableCharsRE": "^[a-z]+$"}'>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
To restrict the pin input to accept only specific numbers, you can use a regular expression. For example, to ensure the pin input accepts only the numbers 1 to 5, set "availableCharsRE"
to "^[1-5]+$"
.
<div class="flex space-x-3" data-pin-input='{"availableCharsRE": "^[1-5]+$"}'>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
Conceal the entered value by setting the type attribute to “password”.
<div class="flex space-x-3" data-pin-input>
<input type="password" class="pin-input" placeholder="○" data-pin-input-item />
<input type="password" class="pin-input" placeholder="○" data-pin-input-item />
<input type="password" class="pin-input" placeholder="○" data-pin-input-item />
<input type="password" class="pin-input" placeholder="○" data-pin-input-item />
</div>
To display a numeric keyboard on iOS (note: this does not apply for Android), Use autocomplete="one-time-code"
and type="tel"
.
<div class="flex space-x-3" data-pin-input='{"availableCharsRE": "^[0-9]+$"}'>
<input type="tel" class="pin-input" placeholder="○" data-pin-input-item autocomplete="one-time-code"/>
<input type="tel" class="pin-input" placeholder="○" data-pin-input-item />
<input type="tel" class="pin-input" placeholder="○" data-pin-input-item />
<input type="tel" class="pin-input" placeholder="○" data-pin-input-item />
</div>
The destroy
method is provided to facilitate the destruction of a pin-input element.
<div id="pin-input-to-destroy" class="flex space-x-3" data-pin-input>
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
<input type="text" class="pin-input" placeholder="○" data-pin-input-item />
</div>
<div class="mt-4 flex gap-3">
<button class="btn btn-primary" id="destroy-btn">Destroy</button>
<button class="btn btn-primary" id="reinit-btn" disabled>Reinitialize</button>
</div>
<script>
window.addEventListener('load', () => {
;(function () {
const pinInput = document.querySelector('#pin-input-to-destroy')
const destroy = document.querySelector('#destroy-btn')
const reinit = document.querySelector('#reinit-btn')
destroy.addEventListener('click', () => {
const { element } = HSPinInput.getInstance(pinInput, true)
element.destroy()
destroy.setAttribute('disabled', 'disabled')
reinit.removeAttribute('disabled')
})
reinit.addEventListener('click', () => {
HSPinInput.autoInit()
reinit.setAttribute('disabled', 'disabled')
destroy.removeAttribute('disabled')
})
})()
});
</script>
PARAMETERS | DESCRIPTION | OPTIONS | DEFAULT VALUE |
---|---|---|---|
data-pin-input | Activate a Pin Input by specifying on an element. | - | - |
:availableCharsRE | String of regular expression for allowed characters. | RegExp | ^[a-zA-Z0-9]+$ |
data-pin-input-item | Identifies the element in the container responsible for data entry. | - | - |
PARAMETERS | DESCRIPTION | OPTIONS | DEFAULT VALUE |
---|---|---|---|
autofocus | If one of the fields has this class, it will be focused when the page loads. | - | - |
HSPinInput
object is contained within the global window
object.METHOD | DESCRIPTION |
---|---|
PUBLIC METHODS | |
destroy() | Destroys the instance, removes generated markup (if any), removes added classes and attributes. |
STATIC METHODS | |
HSPinInput.getInstance(target, isInstance) | Returns the element associated to the target .
|
Destroy instance.
const { element } = HSPinInput.getInstance('#pin-input', true);
const destroyBtn = document.querySelector('#destroy-btn');
destroyBtn.addEventListener('click', () => {
element.destroy();
});
METHOD | DESCRIPTION | RETURNING VALUE |
---|---|---|
on:completed | The event is triggered when the PIN has set up. | Current value |
Assign an ID to data-pin-input
, and you can then trigger an event using that ID.
Below is a demonstration of how to use the event. We’ve included JavaScript to handle the events, allowing it to execute when the corresponding event is fired. To test these events, monitor your console.
<div class="flex space-x-3" data-pin-input id="pin-input-log">
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item autofocus />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
<input type="text" class="pin-input" aria-label="pin input" data-pin-input-item />
</div>
<script>
window.addEventListener('load', function () {
const el = HSPinInput.getInstance('#pin-input-log')
el.on('completed', ({ instance }) => {
console.log('Hello')
})
})
</script>
When pin input is completed example.
const el = HSPinInput.getInstance('#pin-input-log');
el.on('completed', ({instance}) => {console.log("Hello")});