Engrain by ByteRush

WEB.07.01 Mid-level· 11 minCore — asked often

Forms in depth: validation, autocomplete and mobile keyboards

Use the Constraint Validation API for custom messages, autocomplete tokens so browsers fill forms, inputmode and enterkeyhint for the right mobile keyboard, FormData, and :user-invalid styling.

Comes up in: Web fundamentals, UI coding, Machine coding

Learn#

Neha’s sign-up form shows “Please match the requested format.” for a PIN code. Users do not know what format. Half of them leave.

Browsers validate forms from HTML attributes (required, type="email", pattern, min). Constraint validation is the API to read and control that from JavaScript: validity says what is wrong, setCustomValidity() sets your message, and reportValidity() shows it.

const form = document.createElement("form");
form.innerHTML = `
  <input name="email" type="email" required autocomplete="email">
  <input name="pin" inputmode="numeric" pattern="[0-9]{6}" autocomplete="postal-code">`;
const [email, pin] = form.elements;
email.value = "asha@";
pin.value = "4110";
console.log(email.validity.typeMismatch, pin.validity.patternMismatch, form.checkValidity());
pin.setCustomValidity("Enter the 6-digit PIN code");
console.log(pin.validationMessage);
email.value = "asha@example.in";
pin.value = "411001";
pin.setCustomValidity("");
console.log(form.checkValidity(), Object.fromEntries(new FormData(form)));

Output (verified)

true true false
Enter the 6-digit PIN code
true { email: 'asha@example.in', pin: '411001' }

FormData collects every named field, ready to send with fetch.

Validating a PIN code with a clear messageStep 1 of 4

State

  • email.validity.typeMismatch = true
  • pin.validity.patternMismatch = true

Page

    empty

    The user types "asha@" in email and "4110" in PIN code. The browser checks the attributes on every change.

    Read the steps as text
    1. The user types "asha@" in email and "4110" in PIN code. The browser checks the attributes on every change.
    2. On submit, your code reads validity and calls setCustomValidity with a clear message for the PIN field.
    3. reportValidity() shows the message next to the first invalid field and moves focus there.
    4. Fixed values, custom message cleared with setCustomValidity(""): the form is valid, and FormData collects it.

    Predict#

    Predict first

    You call input.setCustomValidity('Too short') and never call it again. The user fixes the value. Is the field valid?

    Interview angle#

    Say it like this — about 30 seconds

    “I start with HTML validation attributes, then use the Constraint Validation API for better messages: check input.validity, set a specific message with setCustomValidity, and show it with reportValidity, or render my own error text linked with aria-describedby. I clear the custom message when the value changes. For filling, I set autocomplete tokens such as email, tel and postal-code, and on mobile I use inputmode for the right keyboard and enterkeyhint for the Enter key’s label. :user-invalid styles errors only after the user interacts.”

    Stays on your device. Nothing is uploaded.
    Follow-up How do you show custom validation messages on a form?
    Read validity, call setCustomValidity(message), then reportValidity(), or show your own text linked with aria-describedby and aria-invalid.
    Follow-up What are inputmode and autocomplete used for?
    inputmode picks the on-screen keyboard (numeric, email, tel); autocomplete tells the browser and password manager what the field is, so they fill it.
    Follow-up Why not type="number" for a PIN code or card number?
    It allows “e” and decimals, may strip leading zeros, and changes on scroll; use inputmode="numeric" with a pattern.

    Practice#

    Guided

    Write accessible validation for a three-field sign-up form: clear messages, aria-invalid, and visible error text.

    Done when

    • Each invalid field gets the right message, aria-invalid="true" and its error text.
    • Fixed fields are cleared: no custom message, no aria-invalid, empty error text.
    • The function returns whether the whole form is valid.
    Your solution
    Ctrl/⌘ + Enter

    Remember#

    Try to answer each card before you open it. Then add them to your reviews.

    What does setCustomValidity("message") do?

    Marks the field invalid with your message, until you call it with "".

    Which property tells you why a field is invalid?

    input.validity (valueMissing, typeMismatch, patternMismatch, …).

    What does inputmode="numeric" do?

    Shows a number keyboard on mobile without number-input quirks.

    Why use :user-invalid instead of :invalid?

    It applies only after the user has interacted, so empty forms are not red at load.

    Go deeper

    Four layers. Stop at the one your interview needs; each ends with a quick check.

    The core ideaEvery round
    An autocomplete token such as email, tel, postal-code or one-time-code tells the browser what a field is. Correct tokens can cut form-filling time sharply, and one-time-code lets phones fill SMS codes Source: HTML Standard: Autofill.
    Check yourself: Name three autocomplete tokens for a delivery form.

    For example name, tel, postal-code, street-address, email.

    How it works underneathSenior rounds
    inputmode (numeric, decimal, tel, email, search, url) picks the keyboard without changing validation. enterkeyhint (next, go, search, send, done) labels the Enter key.
    Check yourself: Which keyboard does inputmode=&quot;decimal&quot; show?

    Numbers with a decimal separator.

    Edge cases and trapsWhere people slip

    Custom elements can join forms with static formAssociated = true and ElementInternals, which gives them setFormValue and their own validity (WEB.19).
    Invalid native forms block submit and focus the first bad field; add novalidate only if you show errors yourself.

    Check yourself: Can a custom element take part in a form?

    Yes, with static formAssociated = true and ElementInternals.

    In productionStaff-level answers

    Style errors with :user-invalid, so untouched fields are not red at load: Chrome 119, Firefox 88, Safari 16.5 Source: MDN: Constraint validation.
    Link each error with aria-describedby so screen readers read it.

    Check yourself: Which pseudo-class styles errors only after interaction?

    :user-invalid

    Finished the five steps? Mark it, and its cards join your reviews.

    Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.

    Interview questions this answers

    • How do you show custom validation messages on a form?
    • What are inputmode and autocomplete used for?