Forms Validation
JavaScript DOM · Reference cheat sheet
Forms Validation
JavaScript DOM · Reference cheat sheet
📋 Overview
Constraint Validation API gives native form checks: required, type, pattern, min/max, minlength/maxlength, and custom validity. Prefer native UI + progressive enhancement; use setCustomValidity for app-specific rules and checkValidity / reportValidity to trigger them.
🔧 Core concepts
- Element APIs:
checkValidity(),reportValidity(),setCustomValidity(msg),validity,validationMessage,willValidate. - Form:
form.checkValidity(),form.reportValidity(),novalidateattribute. - Events:
invalid(cancelable per control),input/changeto clear custom errors. validityflags:valueMissing,typeMismatch,patternMismatch,tooLong,tooShort,rangeUnderflow,rangeOverflow,stepMismatch,customError,valid.- CSS:
:valid,:invalid,:user-valid,:user-invalid.
email.setCustomValidity(
email.validity.typeMismatch ? "Enter a valid email" : "",
);
form.reportValidity();💡 Examples
const form = document.querySelector("form");
const password = form.elements.password;
const confirm = form.elements.confirm;
function syncPasswords() {
confirm.setCustomValidity(
confirm.value !== password.value ? "Passwords must match" : "",
);
}
password.addEventListener("input", syncPasswords);
confirm.addEventListener("input", syncPasswords);
form.addEventListener("submit", (e) => {
syncPasswords();
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity();
return;
}
e.preventDefault();
submitData(new FormData(form));
});
// Live field message
input.addEventListener("invalid", (e) => {
e.preventDefault(); // block browser bubble if custom UI
showError(input, input.validationMessage);
});
input.addEventListener("input", () => {
input.setCustomValidity("");
clearError(input);
});
// Programmatic check without UI
if (username.validity.tooShort) {
/* ... */
}<input
name="username"
required
minlength="3"
pattern="[a-z0-9_]+"
title="Letters, numbers, underscore"
/>⚠️ Pitfalls
setCustomValidity("msg")makes the field invalid until cleared with"".novalidateon form skips native checks — you must validate yourself.- Don’t rely only on client validation — always validate on the server.
:invalidstyles can show too early — prefer:user-invalidwhere supported.- Disabled fields are barred from validation / submission.
🔗 Related
- form.md — form controls
- ../Html/form.md — form HTML
- ../Html/input.md — input types
- focus_blur.md — focusing first error
- events.md — submit/invalid