Forms and Validation

Welcome back.
In the previous lesson, you learned events.
Events help JavaScript react to clicks, typing, forms, and other user actions.
Very useful.
Very interactive.
Very “the button finally does something.”
Today we continue with one of the most important parts of web development.
Forms.
Forms are everywhere.
Contact forms.
Login forms.
Search boxes.
Newsletter signups.
Checkout pages.
Tiny boxes where users type their destiny.
But users are creative.
Very creative.
If you ask for an email, someone will type:
banana
If you ask for a name, someone will type nothing.
If you ask for a password, someone will type:
123
And then act surprised when the website says no.
That is why we need validation.
Validation means checking user input before accepting it.
JavaScript helps us guide users before sending data anywhere.
Like a polite security guard.
But with semicolons.
What You Will Learn
In this lesson, you will learn:
- how forms work in HTML;
- how to select form inputs;
- how to read input values;
- how to validate empty fields;
- how to validate email;
- how to validate password length;
- how to show error messages;
- how to show success messages;
- how to use helper functions;
- how to build a registration form.
By the end of this lesson, you will be able to create forms that check user data before submission.
This is a major step.
Because forms without validation are like doors without handles.
Technically present.
Emotionally confusing.
What Is Form Validation?
Form validation means checking if the data entered by the user is acceptable.
Example:
Name must not be empty.
Email must look like an email.
Password must be long enough.
Message must contain text.
Validation can happen in two places:
- in the browser with JavaScript;
- on the server with backend code.
In this lesson, we focus on frontend validation with JavaScript.
Important:
Frontend validation improves user experience.
But it is not enough for security.
Real applications must also validate data on the backend.
Never trust only the browser.
The browser lives on the user's computer.
And users have buttons.
Dangerous buttons.
Create the Project
Create a folder for this lesson:
mkdir javascript-lesson9
cd javascript-lesson9
touch index.html
touch script.js
Your project should look like this:
javascript-lesson9/
index.html
script.js
Open the folder in your editor.
Today we will build a form, validate it, and show messages.
Small project.
Big lesson.
The form is ready.
The chaos is waiting.
Write the HTML
Open index.html and add this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forms and Validation</title>
</head>
<body>
<h1>Forms and Validation</h1>
<form id="signupForm">
<label for="nameInput">Name</label>
<input id="nameInput" type="text" placeholder="Your name">
<label for="emailInput">Email</label>
<input id="emailInput" type="email" placeholder="you@example.com">
<label for="passwordInput">Password</label>
<input id="passwordInput" type="password" placeholder="At least 6 characters">
<button type="submit">Sign Up</button>
</form>
<p id="message">Fill the form and submit it.</p>
<script src="script.js"></script>
</body>
</html>
This gives us:
- a form;
- a name input;
- an email input;
- a password input;
- a submit button;
- a message area.
Simple.
Clean.
Ready to judge user input politely.
Select the Form and Inputs
Open script.js and add:
const signupForm = document.getElementById("signupForm");
const nameInput = document.getElementById("nameInput");
const emailInput = document.getElementById("emailInput");
const passwordInput = document.getElementById("passwordInput");
const messageElement = document.getElementById("message");
Now JavaScript can access the form and inputs.
These variables represent HTML elements.
But remember:
The input element is not the same as the value inside it.
This:
nameInput
is the input element.
This:
nameInput.value
is what the user typed.
Box.
Content.
Different things.
Like a pizza box and pizza.
Do not eat the box.
Handle Form Submit
Now we add a submit event listener.
function handleSignup(event) {
event.preventDefault();
console.log("Form submitted!");
}
signupForm.addEventListener("submit", handleSignup);
Refresh the browser.
Submit the form.
The page should not reload.
The console should show:
Form submitted!
Why does the page not reload?
Because we used:
event.preventDefault();
By default, forms reload the page when submitted.
But we want JavaScript to handle the form.
So we stop the default behavior.
Without preventDefault, the page reloads, your message disappears, and your confidence goes out for a walk.
Read Input Values
Now let us read the values.
Update handleSignup:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value;
const email = emailInput.value;
const password = passwordInput.value;
console.log(name);
console.log(email);
console.log(password);
}
Type something into the form and submit.
You should see the values in the console.
This is the basic pattern:
const value = input.value;
Very common.
Very important.
Very easy to forget when your brain is debugging five things at once.
Validate Empty Fields
The first validation rule is simple.
Fields must not be empty.
Update handleSignup:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value;
const email = emailInput.value;
const password = passwordInput.value;
if (name === "" || email === "" || password === "") {
messageElement.textContent = "Please fill in all fields.";
return;
}
messageElement.textContent = "Form looks good!";
}
Now submit the form empty.
You should see:
Please fill in all fields.
The return is important.
It stops the function.
If the form is invalid, we show the error and stop.
No need to continue.
Like seeing smoke from the kitchen and deciding not to bake a cake right now.
Wise.
Trim Empty Spaces
There is one problem.
A user can type spaces:
Technically, that is not an empty string.
But it is not a real name either.
So we use .trim().
Example:
const name = nameInput.value.trim();
.trim() removes spaces from the beginning and end of a string.
Update the code:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const password = passwordInput.value.trim();
if (name === "" || email === "" || password === "") {
messageElement.textContent = "Please fill in all fields.";
return;
}
messageElement.textContent = "Form looks good!";
}
Now spaces alone will not pass validation.
Good.
Users are creative.
But we are learning.
Validate Email
A simple email check can use .includes().
Example:
if (!email.includes("@")) {
messageElement.textContent = "Please enter a valid email.";
return;
}
This is not perfect email validation.
Email validation can become surprisingly complicated.
Very complicated.
Like opening a drawer and finding another drawer inside.
For beginners, checking for @ is enough to understand the idea.
Update the function:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const password = passwordInput.value.trim();
if (name === "" || email === "" || password === "") {
messageElement.textContent = "Please fill in all fields.";
return;
}
if (!email.includes("@")) {
messageElement.textContent = "Please enter a valid email.";
return;
}
messageElement.textContent = "Form looks good!";
}
Now if the user types:
banana
JavaScript says no.
Politely.
But firmly.
Validate Password Length
Now let us check password length.
Example:
if (password.length < 6) {
messageElement.textContent = "Password must be at least 6 characters.";
return;
}
Add it to the function:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const password = passwordInput.value.trim();
if (name === "" || email === "" || password === "") {
messageElement.textContent = "Please fill in all fields.";
return;
}
if (!email.includes("@")) {
messageElement.textContent = "Please enter a valid email.";
return;
}
if (password.length < 6) {
messageElement.textContent = "Password must be at least 6 characters.";
return;
}
messageElement.textContent = "Form looks good!";
}
Now the form checks:
- empty fields;
- email format;
- password length.
This is already useful.
Not perfect.
But useful.
Like a chair with all four legs.
A good start.
Add Better Styles
Now let us make the form look better.
Update index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Forms and Validation</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 700px;
margin: 60px auto;
padding: 0 24px;
background-color: #f3f4f6;
color: #111827;
}
.card {
background-color: white;
padding: 24px;
border: 2px solid #e5e7eb;
border-radius: 18px;
}
h1 {
font-size: 42px;
}
label {
display: block;
margin-top: 16px;
font-weight: 700;
}
input {
width: 100%;
margin-top: 8px;
padding: 12px;
border: 2px solid #d1d5db;
border-radius: 12px;
font-size: 18px;
box-sizing: border-box;
}
button {
margin-top: 18px;
background-color: #2563eb;
color: white;
border: none;
padding: 14px 20px;
border-radius: 999px;
font-weight: 700;
cursor: pointer;
}
button:hover {
background-color: #1d4ed8;
}
.message {
margin-top: 20px;
padding: 16px;
border-radius: 14px;
background-color: #eff6ff;
border: 2px solid #bfdbfe;
}
.error {
background-color: #fef2f2;
border-color: #fecaca;
color: #991b1b;
}
.success {
background-color: #ecfdf5;
border-color: #bbf7d0;
color: #166534;
}
</style>
</head>
<body>
<h1>Forms and Validation</h1>
<div class="card">
<form id="signupForm">
<label for="nameInput">Name</label>
<input id="nameInput" type="text" placeholder="Your name">
<label for="emailInput">Email</label>
<input id="emailInput" type="email" placeholder="you@example.com">
<label for="passwordInput">Password</label>
<input id="passwordInput" type="password" placeholder="At least 6 characters">
<button type="submit">Sign Up</button>
</form>
<p id="message" class="message">Fill the form and submit it.</p>
</div>
<script src="script.js"></script>
</body>
</html>
Now the form looks like it belongs to a website.
Not to a document from 1998.
Progress.
Create Helper Functions
Our validation works.
But we repeat this line many times:
messageElement.textContent = "...";
Let us create a helper function.
Update script.js:
const signupForm = document.getElementById("signupForm");
const nameInput = document.getElementById("nameInput");
const emailInput = document.getElementById("emailInput");
const passwordInput = document.getElementById("passwordInput");
const messageElement = document.getElementById("message");
function showMessage(text, type) {
messageElement.textContent = text;
messageElement.className = `message ${type}`;
}
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const password = passwordInput.value.trim();
if (name === "" || email === "" || password === "") {
showMessage("Please fill in all fields.", "error");
return;
}
if (!email.includes("@")) {
showMessage("Please enter a valid email.", "error");
return;
}
if (password.length < 6) {
showMessage("Password must be at least 6 characters.", "error");
return;
}
showMessage(`Welcome, ${name}! Your account data looks valid.`, "success");
}
signupForm.addEventListener("submit", handleSignup);
Much cleaner.
Now this:
showMessage("Please fill in all fields.", "error");
updates both text and style.
Helper functions help us avoid repetition.
And repetition in code is like socks disappearing in the washing machine.
At first it is funny.
Then it becomes a lifestyle problem.
Clear Inputs After Success
If the form is valid, we can clear the inputs.
Add this after the success message:
nameInput.value = "";
emailInput.value = "";
passwordInput.value = "";
Full success part:
showMessage(`Welcome, ${name}! Your account data looks valid.`, "success");
nameInput.value = "";
emailInput.value = "";
passwordInput.value = "";
Now after a successful submit, the form becomes empty again.
This is a common pattern.
Submit.
Show message.
Clear fields.
Civilized behavior.
Very rare in badly built forms.
Full JavaScript Code
Here is the full script.js:
const signupForm = document.getElementById("signupForm");
const nameInput = document.getElementById("nameInput");
const emailInput = document.getElementById("emailInput");
const passwordInput = document.getElementById("passwordInput");
const messageElement = document.getElementById("message");
function showMessage(text, type) {
messageElement.textContent = text;
messageElement.className = `message ${type}`;
}
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const password = passwordInput.value.trim();
if (name === "" || email === "" || password === "") {
showMessage("Please fill in all fields.", "error");
return;
}
if (!email.includes("@")) {
showMessage("Please enter a valid email.", "error");
return;
}
if (password.length < 6) {
showMessage("Password must be at least 6 characters.", "error");
return;
}
showMessage(`Welcome, ${name}! Your account data looks valid.`, "success");
nameInput.value = "";
emailInput.value = "";
passwordInput.value = "";
}
signupForm.addEventListener("submit", handleSignup);
This is now a real interactive form.
It reads input.
Checks data.
Shows messages.
Clears fields.
No backend yet.
No database yet.
No server dragons yet.
But this is real frontend behavior.
Common Mistakes
Forgetting preventDefault
Wrong:
function handleSignup(event) {
const name = nameInput.value;
}
Correct:
function handleSignup(event) {
event.preventDefault();
const name = nameInput.value;
}
Without preventDefault, the page may reload.
Then your JavaScript message disappears.
Then you accuse the computer.
Then you remember the missing line.
Forgetting .value
Wrong:
const email = emailInput;
Correct:
const email = emailInput.value;
The input element is the box.
The value is what the user typed.
Do not validate the box.
Validate the content.
Pizza rule again.
Forgetting return
Wrong:
if (password.length < 6) {
showMessage("Password is too short.", "error");
}
showMessage("Success!", "success");
This shows an error and then success.
Confusing.
Correct:
if (password.length < 6) {
showMessage("Password is too short.", "error");
return;
}
showMessage("Success!", "success");
return stops the function.
Very useful.
Very underrated.
Like sleep.
Checking Email Too Simply
This is simple:
email.includes("@")
It is good for learning.
But real email validation is more complex.
For now, the goal is to understand validation logic.
Not become the international minister of email formats.
Practice
Create a contact form with:
- name;
- email;
- message.
Rules:
- name must not be empty;
- email must include
@; - message must be at least 10 characters long.
Show error messages when something is wrong.
Show a success message when everything is correct.
Example success message:
Thank you! Your message is ready to send.
Remember:
This does not actually send the message.
It only validates the form.
Still useful.
Still important.
Still frontend.
Mini Challenge
Create a password confirmation form.
The form should have:
- password input;
- confirm password input;
- submit button;
- message area.
Rules:
- password must not be empty;
- password must be at least 6 characters;
- confirm password must match password.
If everything is correct, show:
Password confirmed.
If not, show a helpful error.
This is very common in real websites.
Users often type passwords twice.
Because apparently one password field was not enough emotional pressure.
Summary
Today you learned:
- forms collect user input;
- JavaScript can read input values with
.value; - form submissions can be handled with
submit; preventDefaultstops page reload;- validation checks if data is acceptable;
.trim()removes extra spaces;- empty fields can be checked with
=== ""; - email can be checked with simple conditions;
- password length can be checked with
.length; - helper functions reduce repetition;
- error and success messages improve user experience.
This is a huge step.
Forms are everywhere.
Validation is everywhere.
Users type strange things everywhere.
JavaScript helps us bring order.
Not perfect order.
But enough order to survive.
Next Lesson
In the next lesson, we will learn local storage.
Local storage lets JavaScript save data in the browser.
That means the page can remember things even after refresh.
Tasks.
Settings.
Names.
Small pieces of data.
Finally, JavaScript gets a tiny memory.
Dangerous.
But useful.