Chapter 27 of 31

JavaScript Forms & Form Validation

Forms are everywhere on the web.

Whenever you log in, create an account, search for something, place an order, or submit your contact details, you're probably interacting with a form.

HTML provides the structure for forms, but JavaScript allows us to make them interactive and validate the data before it is submitted.

For example, we might want to check:

  • Is the name filled in?

  • Is the email valid?

  • Is the password long enough?

  • Are required fields completed?

  • Should the form be submitted or rejected?

This is where form validation becomes useful.

What is a Form?

An HTML <form> is a container used to collect information from users.

For example:

<form id="signupForm">
    <input type="text" id="username">
    <input type="email" id="email">
    <button type="submit">Sign Up</button>
</form>

JavaScript can access these fields and respond when the user submits the form.


Handling Form Submission

The most common event for forms is the submit event.

const form = document.querySelector("#signupForm");

form.addEventListener("submit", (event) => {
    console.log("Form submitted!");
});

Whenever the user submits the form, this function runs.

But there's an important thing to understand.

By default, the browser may reload the page or navigate somewhere when a form is submitted.

We can prevent that behavior using:

event.preventDefault();

For example:

form.addEventListener("submit", (event) => {
    event.preventDefault();

    console.log("Form submitted!");
});

Now JavaScript can handle the form submission itself.


Getting Form Values

We can access an input's value using .value.

Suppose we have:

<input type="text" id="username">

We can get its value with:

const username = document.querySelector("#username");

console.log(username.value);

If the user enters:

John

then:

username.value

contains:

John

A Simple Form Example

HTML:

<form id="loginForm">
    <input type="text" id="username" placeholder="Username">
    <input type="password" id="password" placeholder="Password">

    <button type="submit">Login</button>
</form>

JavaScript:

const form = document.querySelector("#loginForm");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    const username = document.querySelector("#username").value;
    const password = document.querySelector("#password").value;

    console.log(username);
    console.log(password);
});

Now we can use those values for validation or send them to a server.


What is Form Validation?

Form validation is the process of checking whether the data entered by a user meets the required rules before accepting or processing it.

For example:

Username → Required
Email    → Must be valid
Password → At least 8 characters
Age      → Must be 18 or above

Validation helps prevent incorrect or incomplete data from being processed.


Required Fields

HTML already provides some basic validation features.

For example:

<input type="text" id="username" required>

The required attribute tells the browser that the field cannot be empty.

You can also specify an email field:

<input type="email" id="email" required>

The browser will perform basic email-format validation when the form is submitted.

This is called HTML constraint validation.

JavaScript can also perform custom validation when we need more control.


Validating with JavaScript

Suppose we want to make sure the username isn't empty.

const form = document.querySelector("#loginForm");
const username = document.querySelector("#username");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    if (username.value.trim() === "") {
        console.log("Username is required.");
        return;
    }

    console.log("Form is valid.");
});

Here:

username.value.trim() === ""

checks whether the user entered only whitespace or nothing at all.


Validating Password Length

Suppose we require a password to contain at least 8 characters.

const password = document.querySelector("#password");

if (password.value.length < 8) {
    console.log("Password must contain at least 8 characters.");
}

We can combine this with the form:

form.addEventListener("submit", (event) => {
    event.preventDefault();

    if (password.value.length < 8) {
        console.log("Password is too short.");
        return;
    }

    console.log("Password is valid.");
});

Validating Email

We can use an <input type="email"> for basic browser validation:

<input type="email" id="email" required>

We can also check it from JavaScript using the browser's built-in validation:

const email = document.querySelector("#email");

if (!email.checkValidity()) {
    console.log("Please enter a valid email.");
}

The browser's email validation is useful for basic checks, but remember that client-side validation should never be your only validation. Data sent to a server should be validated again on the server.


Using Regular Expressions

For custom text patterns, we can use regular expressions.

For example:

const usernamePattern = /^[a-zA-Z0-9_]+$/;

const username = "john_123";

console.log(usernamePattern.test(username));

Output:

true

Regular expressions can be useful for checking patterns such as usernames, postal codes, or specific formats.

However, don't make validation unnecessarily complicated. Use built-in HTML validation when it is sufficient, and use regular expressions when you genuinely need a custom pattern.


Showing Error Messages

Simply printing errors to the console isn't very helpful to users.

Instead, we can display the error directly on the webpage.

HTML:

<form id="signupForm">
    <input type="text" id="username">

    <p id="error"></p>

    <button type="submit">Sign Up</button>
</form>

JavaScript:

const form = document.querySelector("#signupForm");
const username = document.querySelector("#username");
const error = document.querySelector("#error");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    if (username.value.trim() === "") {
        error.textContent = "Username is required.";
        return;
    }

    error.textContent = "Form submitted successfully!";
});

Now the user gets feedback directly on the page.


Validating Multiple Fields

Real forms usually contain several fields.

For example:

<form id="signupForm">
    <input type="text" id="username">
    <input type="email" id="email">
    <input type="password" id="password">

    <button type="submit">Create Account</button>
</form>

We can validate all of them:

const form = document.querySelector("#signupForm");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    const username = document.querySelector("#username").value.trim();
    const email = document.querySelector("#email").value.trim();
    const password = document.querySelector("#password").value;

    if (username === "") {
        console.log("Username is required.");
        return;
    }

    if (email === "") {
        console.log("Email is required.");
        return;
    }

    if (password.length < 8) {
        console.log("Password must be at least 8 characters.");
        return;
    }

    console.log("Form is valid!");
});

The return statements stop the function when an invalid value is found.


Useful Constraint Validation Properties

HTML form controls provide several useful properties and methods.

Property / Method

Purpose

value

Gets the entered value

required

Makes a field required

validity

Provides detailed validation information

checkValidity()

Checks whether the field/form is valid

reportValidity()

Checks validity and shows browser feedback

setCustomValidity()

Sets a custom validation message

For example:

const email = document.querySelector("#email");

if (!email.checkValidity()) {
    console.log("Invalid email.");
}

Custom Validation with setCustomValidity()

Sometimes we want to create our own validation rule.

For example:

const username = document.querySelector("#username");

username.addEventListener("input", () => {
    if (username.value.length < 3) {
        username.setCustomValidity(
            "Username must contain at least 3 characters."
        );
    } else {
        username.setCustomValidity("");
    }
});

An empty string means the custom error has been cleared.

Now the browser's built-in form validation system can use our custom rule.


Validating While the User Types

Validation doesn't always have to happen when the user presses Submit.

We can use the input event:

const username = document.querySelector("#username");

username.addEventListener("input", () => {
    if (username.value.length < 3) {
        console.log("Username is too short.");
    } else {
        console.log("Username looks good.");
    }
});

This allows us to provide live feedback.

For example:

User types: Jo
→ Username is too short.

User types: John
→ Username looks good.

This is commonly used in modern forms.


Resetting a Form

JavaScript can also reset all form fields.

form.reset();

For example:

const form = document.querySelector("#signupForm");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    console.log("Submitted!");

    form.reset();
});

After the form is processed, all fields return to their initial values.


A Practical Example

Let's build a simple registration form.

HTML

<form id="signupForm">
    <input type="text" id="username" placeholder="Username">
    <input type="email" id="email" placeholder="Email">
    <input type="password" id="password" placeholder="Password">

    <p id="message"></p>

    <button type="submit">Create Account</button>
</form>

JavaScript

const form = document.querySelector("#signupForm");
const message = document.querySelector("#message");

form.addEventListener("submit", (event) => {
    event.preventDefault();

    const username = document.querySelector("#username").value.trim();
    const email = document.querySelector("#email").value.trim();
    const password = document.querySelector("#password").value;

    if (username === "") {
        message.textContent = "Username is required.";
        return;
    }

    if (email === "") {
        message.textContent = "Email is required.";
        return;
    }

    if (password.length < 8) {
        message.textContent = "Password must be at least 8 characters.";
        return;
    }

    message.textContent = "Account created successfully!";
});

Now the form checks each field before accepting the submission.

The flow is:

User submits form
       ↓
Get input values
       ↓
Validate fields
       ↓
Invalid? → Show error
       ↓
Valid? → Continue processing

Client-Side vs Server-Side Validation

One very important point: JavaScript validation in the browser is not enough for security.

A user can disable JavaScript, modify the page, or send a request directly to your server without using your form.

So a real application should generally use:

Client-side validation
        ↓
Better user experience

Server-side validation
        ↓
Actual data protection

Client-side validation makes the interface convenient, while server-side validation is essential for trusting and processing submitted data safely.

Conclusion

Forms allow users to provide information, while JavaScript lets us read, validate, and process that information.

The important concepts to remember are:

  • Use the submit event to handle form submission.

  • Use .value to read input values.

  • Use event.preventDefault() when you need to prevent the browser's default submission behavior.

  • Use HTML attributes like required, type, min, max, and pattern for built-in validation.

  • Use JavaScript for custom validation rules.

  • checkValidity() and reportValidity() work with the browser's validation system.

  • setCustomValidity() lets you add custom validation messages.

  • Always validate important data on the server as well.

Once you understand forms and validation, you're ready to build practical features such as login forms, registration pages, search boxes, contact forms, checkout forms, and profile forms.