Select Page

Here is a code with the demo I just found on Codepen, that handles pasting OTP also.

See the Pen OTP Field by Puneet Sharma (@webdevpuneet) on CodePen.

HTML

<body>
    <h1>Enter OTP</h1>
    <div class="otp-field">
        <input type="text" maxlength="1" />
        <input type="text" maxlength="1" />
        <input class="space" type="text" maxlength="1" />
        <input type="text" maxlength="1" />
        <input type="text" maxlength="1" />
        <input type="text" maxlength="1" />
    </div>
</body>

CSS

body {
    margin: 0;
    font-family: "Poppins", sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    background: #282a36;
    height: 100vh;
    color: #fff;
}

.otp-field {
    display: flex;
}

.otp-field input {
    width: 24px;
    font-size: 32px;
    padding: 10px;
    text-align: center;
    border-radius: 5px;
    margin: 2px;
    border: 2px solid #55525c;
    background: #21232d;
    font-weight: bold;
    color: #fff;
    outline: none;
    transition: all 0.1s;
}

.otp-field input:focus {
    border: 2px solid #a527ff;
    box-shadow: 0 0 2px 2px #a527ff6a;
}

.disabled {
    opacity: 0.5;
}

.space {
    margin-right: 1rem !important;
}

JavaScript

const inputs = document.querySelectorAll(".otp-field input");

inputs.forEach((input, index) => {
    input.dataset.index = index;
    input.addEventListener("keyup", handleOtp);
    input.addEventListener("paste", handleOnPasteOtp);
});

function handleOtp(e) {
    /**
     * <input type="text" 👉 maxlength="1" />
     * 👉 NOTE: On mobile devices `maxlength` property isn't supported,
     * So we to write our own logic to make it work. 🙂
     */
    const input = e.target;
    let value = input.value;
    let isValidInput = value.match(/[0-9a-z]/gi);
    input.value = "";
    input.value = isValidInput ? value[0] : "";

    let fieldIndex = input.dataset.index;
    if (fieldIndex < inputs.length - 1 && isValidInput) {
        input.nextElementSibling.focus();
    }

    if (e.key === "Backspace" && fieldIndex > 0) {
        input.previousElementSibling.focus();
    }

    if (fieldIndex == inputs.length - 1 && isValidInput) {
        submit();
    }
}

function handleOnPasteOtp(e) {
    const data = e.clipboardData.getData("text");
    const value = data.split("");
    if (value.length === inputs.length) {
        inputs.forEach((input, index) => (input.value = value[index]));
        submit();
    }
}

function submit() {
    console.log("Submitting...");
    // 👇 Entered OTP
    let otp = "";
    inputs.forEach((input) => {
        otp += input.value;
        input.disabled = true;
        input.classList.add("disabled");
    });
    console.log(otp);
    // 👉 Call API below
}