Lesson 3.10: JavaScript Form Validation
JavaScript Form Validation
Stop bad data before it ever leaves the page. Learn how JavaScript checks your contact form — blocking empty fields, catching invalid emails, and giving users instant, helpful feedback.
Lesson Objectives
- Explain what client-side form validation is and why it improves user experience
- Read form field values using
element.valueand clean them with.trim() - Use
addEventListener('submit', ...)andevent.preventDefault()to intercept form submission - Write a validation function that checks for empty fields and a valid email format
- Display inline error messages using DOM manipulation rather than blocking
alert()dialogs - Show a success message when all fields pass validation
Part 1: Why Validate Forms?
Your contact form (built in Lesson 3.2) can currently be submitted completely empty — or with a fake email address like notanemail. That's a problem. Form validation catches these issues before data goes anywhere, giving users instant, friendly feedback so they can fix the problem right away.
Without validation, users can submit:
- ❌ A completely blank name field
- ❌ A missing or malformed email address (e.g.,
hellowith no@) - ❌ An empty message box
Two Layers of Validation
| Type | How It Works | What It Can Do | Limitation |
|---|---|---|---|
| HTML5 Built-in | required, type="email" attributes on inputs |
Blocks empty required fields; checks basic email format | Browser tooltips only — no custom messages or styling |
| JavaScript Custom | A function that runs when the form is submitted | Custom error messages, field highlighting, success feedback, complex rules | Can be bypassed if JavaScript is disabled |
required attribute and type="email" on your inputs and add JavaScript validation. HTML5 provides a baseline safety net; JavaScript provides the polished, user-friendly experience. Never rely on client-side validation alone for security — a real server should always validate too.
Part 2: How Validation Works
When a user clicks Submit, JavaScript intercepts the event, reads each field's value, runs checks, and either shows an error or allows the form to proceed. Here is the logic as a flow:
Form's submit event fires
Stops the form from sending immediately
Get name, email, message — strip whitespace
All fields valid — form can proceed
Key JavaScript Techniques Used
Part 3: The Complete Validation Function
Here is the full validation pattern — from the HTML form update to the complete JavaScript function. Study each part and its comment carefully before implementing it on your own site.
Step 1 — Update the HTML Form
Make sure your form has id="contactForm" and your fields have matching IDs. We give the error message elements their own <span> tags so JavaScript can write into them:
novalidate? Adding novalidate to the <form> tag turns off the browser's built-in HTML5 validation popups. This lets your JavaScript show its own custom inline error messages instead — giving you full control over the user experience.
Step 2 — The CSS for Error & Success States
Step 3 — The JavaScript Validation Function
Part 4: See It in Action
This is a fully working validated form. Try submitting it with various combinations of empty and filled fields to see the inline error messages and success state in action.
Try submitting empty, with a bad email, or fully filled out. Watch the inline error messages and green success state appear.
Student Activity
Make Your Form Smarter with JavaScript Validation
Title: Make Your Form Smarter with JavaScript Validation | Platform: Knowledge Pillars Coding Lab
You built your contact form in Lesson 3.2 and gave it id="contactForm". Now add JavaScript that intercepts submission, checks every field, shows inline errors, and confirms success — without ever blocking the page with an alert().
-
Add
novalidateand error spans to your form inindex.html. Update your existing form tag and add an error<span>after each input and a success paragraph at the end:<!-- Update your <form> tag --> <form id="contactForm" action="#" method="POST" novalidate> <!-- After your name input --> <span id="name-error" class="error-msg" aria-live="polite"></span> <!-- After your email input --> <span id="email-error" class="error-msg" aria-live="polite"></span> <!-- After your textarea --> <span id="message-error" class="error-msg" aria-live="polite"></span> <!-- Success message — after your submit button --> <p id="form-success"></p> </form>💾 Save
index.html. -
Add the error styling to
style.css..error-msg { display: block; color: #b91c1c; font-size: .85rem; font-weight: 700; min-height: 20px; margin-bottom: 8px; } input.error, textarea.error { border: 2px solid #b91c1c; background-color: #fff5f5; } input.success, textarea.success { border: 2px solid #16a34a; background-color: #f0fdf4; } #form-success { color: #14532d; font-weight: 700; margin-top: 10px; }💾 Save
style.css. -
Add the validation script just before
</body>inindex.html. Add this inside your existing<script>block (or a new one):let form = document.getElementById('contactForm'); form.addEventListener('submit', function(event) { event.preventDefault(); let name = document.getElementById('name').value.trim(); let email = document.getElementById('email').value.trim(); let message = document.getElementById('message').value.trim(); let valid = true; ['name', 'email', 'message'].forEach(function(id) { document.getElementById(id).classList.remove('error', 'success'); document.getElementById(id + '-error').textContent = ''; }); document.getElementById('form-success').textContent = ''; if (name === '') { document.getElementById('name-error').textContent = 'Name is required.'; document.getElementById('name').classList.add('error'); valid = false; } else { document.getElementById('name').classList.add('success'); } if (email === '') { document.getElementById('email-error').textContent = 'Email is required.'; document.getElementById('email').classList.add('error'); valid = false; } else if (!email.includes('@')) { document.getElementById('email-error').textContent = 'Please enter a valid email address.'; document.getElementById('email').classList.add('error'); valid = false; } else { document.getElementById('email').classList.add('success'); } if (message === '') { document.getElementById('message-error').textContent = 'Message cannot be empty.'; document.getElementById('message').classList.add('error'); valid = false; } else { document.getElementById('message').classList.add('success'); } if (valid) { document.getElementById('form-success').textContent = '✅ Thank you! Your message has been sent.'; form.reset(); } });💾 Save both files and test your form thoroughly — try all the error combinations!
🌟 Bonus Challenges
Check minimum message length (at least 10 characters):
Live character counter for the message field:
Vocabulary
true if the string contains the given substring — used here to check for a valid email formatLesson Summary
| Concept / Method | What It Does |
|---|---|
novalidate on <form> | Disables browser HTML5 validation popups — hands full control to your JavaScript |
addEventListener('submit', fn) | Listens for the form's submit event — fires the validation function before anything is sent |
event.preventDefault() | Stops the default form submission — keeps the user on the page while validation runs |
element.value.trim() | Reads the field's value and strips leading/trailing whitespace |
if (name === '') | Checks whether a field is empty — the core empty-field validation |
!email.includes('@') | Returns true if the email is missing an @ symbol — basic email format check |
Inline error messages via textContent | Writes error text directly into a <span> next to the field — no alert() needed |
classList.add('error') | Adds a red-border CSS class to the failing field for clear visual feedback |
classList.add('success') | Adds a green-border class when a field passes validation |
form.reset() | Clears all fields after successful submission |
| Client-side only | Always validate on the server too — client-side validation improves UX but is not a security measure |
Knowledge Check
Read each question carefully and select the best answer. Each question has one correct response.
1. What does event.preventDefault() do inside a form's submit handler?
2. Why is .trim() used when reading form field values?
3. What does !email.includes('@') check?
4. What is the purpose of adding novalidate to the <form> tag?
5. Why is client-side JavaScript validation alone not enough for a real production website?
Activity Checklist
- I added
novalidateto my<form>tag - I added
<span class="error-msg">elements after each input field with matching IDs - I added a
<p id="form-success">element after the submit button - I added
.error-msg,input.error,input.successCSS rules tostyle.css - I used
addEventListener('submit', ...)to attach my validation function - I called
event.preventDefault()at the start of the handler - I used
.value.trim()to read and clean each field's value - I check for empty name, empty/invalid email, and empty message — setting
valid = falseon any failure - Errors are shown via
textContentin the span elements andclassList.add('error')on the fields - On success I show a confirmation message and call
form.reset() - I tested all error scenarios: empty submit, bad email, partial fill, and fully valid submission
- I saved both files and committed my changes in the Knowledge Pillars Coding Lab
