JavaScript · The DOM

Form Validation

HTML validates simple rules on its own. JavaScript adds rules HTML can’t express — like “passwords must match” — and friendlier messages.

Intermediate 5 min Lesson 30 of 49 Runnable examples
0/49 in JavaScript
On this page · 5 min · Intermediate

Learning objectives#

  • Use checkValidity and validationMessage
  • Add custom rules with setCustomValidity
  • Show errors near the field and focus it
  • Remember that the server must validate too

Explanation#

Every input has a validity state built from HTML attributes such as required, type="email" and minlength.

form.checkValidity() returns true if every field is valid. input.validationMessage gives the browser’s message.

input.setCustomValidity('message') marks a field invalid with your own message; setCustomValidity('') clears it.

Client-side validation helps users; it is not security. Always validate again on the server.

Code example: Sign-up form with a password match#

HTMLSign-up form with a password match Runnable
<style>label{display:block;margin:8px 0} #msg{color:#b91c1c;font-weight:600}</style>
<form id="signup" novalidate>
  <label>Email <input id="email" type="email" required></label>
  <label>Password <input id="pw" type="password" required minlength="8"></label>
  <label>Confirm <input id="pw2" type="password" required></label>
  <button>Sign up</button>
  <p id="msg" role="alert"></p>
</form>


<script>
  const form = document.querySelector('#signup');
  const msg = document.querySelector('#msg');


  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const pw = form.querySelector('#pw'), pw2 = form.querySelector('#pw2');
    pw2.setCustomValidity(pw.value === pw2.value ? '' : 'Passwords do not match');


    if (!form.checkValidity()) {
      const firstBad = form.querySelector(':invalid');
      msg.textContent = firstBad.validationMessage;
      firstBad.focus();
      return;
    }
    msg.style.color = '#15803d';
    msg.textContent = '✓ All good — ready to send!';
  });
</script>
Expected output
Submitting shows the first problem (for example “Passwords do not match”) and focuses that field; a valid form shows a green success message.
Opens this example in the full playground

Step-by-step explanation#

  1. novalidate turns off the browser’s pop-up bubbles so we can show our own message.
  2. The custom rule sets or clears an error on the confirm field.
  3. checkValidity checks every rule, built-in and custom.
  4. :invalid finds the first bad field so we can show its message and focus it.

Real-world use case#

Registration, checkout and contact forms combine HTML rules with a few JavaScript checks for a smooth experience.

Common mistakes#

Never clearing a custom error

If you do not call setCustomValidity('') when the value becomes valid, the field stays invalid forever.

Only validating in the browser

Requests can be sent directly to your API. Validate on the server as well.

Best practices#

  • Use HTML attributes first, JavaScript for extra rules
  • Show errors next to the field and announce them (role="alert")
  • Focus the first invalid field
  • Validate again on the server

Remember this#

HTML rules first, JavaScript for the rest.

setCustomValidity('msg') = invalid; setCustomValidity('') = valid again.

Browser validation is for users; server validation is for security.

Practice exercise#

Your task: Add a rule that the email must end with "@example.com", with the message “Use your company email”.

Show solution
JavaScript Illustrative
const email = form.querySelector('#email');
email.setCustomValidity(email.value.endsWith('@example.com') ? '' : 'Use your company email');

Mini quiz#

Form Validation quizMultiple choice Question 1 of 1

How do you mark a field valid again after a custom error?

Score so far: 0/0

Want more? Practise all JavaScript MCQs · JavaScript interview questions

My notes#

Saved in this browser.

Progress is saved in this browser. Sign in to sync.