Form Validation with JavaScript
Tags: javascript, webdev, tutorial, frontend
Published: 2023-06-03 17:44:54

**Before submitting data to the server, It is important to ensure all required form controls are filled out, in the correct format. This is called client-side form validation and helps ensure data submitted matches the requirements set forth in the various form controls.**

## HTML Validation
Although validation can also be done with HTML attributes like - `required`, `minlength`, `maxlength`, `min`, `max`, `type`, and `pattern`. The downside of it is that you can't customize it to fit your requirements.

## What is Form Validation?
Have you ever tried to sign up on a website where they had certain requirements? Like:

- Ensuring your password is between 8 to 30 characters or making sure your password is mixed between letters, numbers, and asterisks.
- Or ensure you include the @ for the email input field by popping messages like "Please enter a valid email address".
- "This field is required" (You can't leave this field blank)

This is called Validation. When you enter your details on a form website, the browser and/or the web server will check to see that the data is in the correct format and within the constraints set by the application.

Form validation is the process of verifying that the data entered into an HTML form is accurate, complete, and meets the specified criteria before it is submitted to the server.

The application allows the data to be submitted to the server if the information is correctly formatted. If the information is not correctly formatted, it gives the user an error message explaining what needs to be corrected.

## Building A Form
Let's build a form webpage in order to solidify our understanding of form validation.

## The HTML Code

```
<div class="formContainer">
        <header>
            <h1>Sign In</h1>
            <a href="test1.html">CHECK</a>
        </header>

        <form id="myForm">
            <div class="formDetails">
                <label for="name">Name:</label>
                <input type="text" id="name" name="name">
                <div class="errorMessage"></div>
            </div>

            <div class="formDetails">
                <label for="email">Email:</label>
                <input type="email" id="email" name="email">
                <div class="errorMessage"></div>
            </div>

            <div class="formDetails">
                <label for="password">Password:</label>
                <input type="password" id="password" name="password">
                <div class="errorMessage"></div>
            </div>

            <div class="formDetails">
                <label for="confirmpassword">Confirm Password:</label>
                <input type="password" id="confirmPassword" name="confirmpassword">
                <div class="errorMessage"></div>
            </div>

            <button id="button" type="submit">Submit</button>
          </form>
    </div>
```

- The HTML code defines a form with four input fields: `name`, `email`, `password`, and `confirm password`. Each input field is wrapped in a div element with a class of `formDetails`.
- Below each input field, there is a `div` element with a class of `errorMessage`. This is where any error messages related to the corresponding input field will be displayed.
- The form also has a submit button with an id of button. This button triggers the form submission when clicked.

## The CSS Code

```
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body{
    background-color: #021012;
    font-family: sans-serif;
}

.formContainer{
    width: 80%;
    height: 85vh;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background-color: #E2F4FD;
}
header{
    text-align: center;
    margin: 2rem 0;
    font-weight: 600;
}

#myForm{
    width: 90%;
    margin: 1rem auto;
}

.formDetails{
    margin: 1rem 0;
}

label{
    display: block;
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: .4rem;
}

input{
    width: 100%;
    padding: .6rem 0;
    outline: none;
    font-size: 1rem;
}

input:focus{
    outline: 1px solid #064247;
}
button{
    margin: 1.1rem 0;
    background-color: #053135;
    color: #fff;
    font-weight: 600;
    border: none;
    padding: .8rem 0;
    width: 100%;
}
.errorMessage{
    margin-top: .3rem;
    font-size: .9rem;
    font-weight: 600;
    font-family: monospace;
}
.formDetails.success input {
    border-color: #09c372;
    outline: none;
  }

  .formDetails.error input {
    border-color: #f2070e;
  }

@media screen and (min-width: 1024px) {
    .formContainer{
        width: 30%;
    }
}
```

- The `.formContainer` selector sets the `width` of the form container to `80%` of the parent element, and the `height` to `85%` of the viewport height, and positions it in the center of the screen using `absolute` positioning and the `transform` property - `transform: translate(-50%, -50%)`. The background color is set to a light shade of blue - `#021012`.
- The `input` and `button` selectors set the width to `100%` of the parent container, padding to `0.6rem` at the top and bottom of the `input` selector, `outline` to `none`, and font size to `1rem`. There is also a focus state added to the input selector that outlines the input with a `1px solid` border in a different color.
- The `.formDetails.success` input selector applies the styles to the input element when the `.formDetails` container has a class of `success`. It sets the border color to a light shade of green and the outline to none.
- The `.formDetails.error` input selector applies the styles to the input element when the `.formDetails` container has a class of `error`. It sets the border color to a dark shade of red.


```
@media screen and (min-width: 1024px) {
    .formContainer{
        width: 30%;
    }
}
```

- The `@media` rule creates a media query that applies styles when the screen width is above 1024px. In this case, the width of the `.formContainer` is set to 30% of the parent element. This makes the form container smaller when viewed on larger screens.

## JavaScript For Validation

- The code listens for the form submission event and prevents the form from submitting by default. It then performs validations on each input field and displays appropriate error messages in the `errorMessage` divs and applies the success and error classes to the parent `formDetails` divs based on the validation result.


```
const myForm = document.getElementById('myForm');
myForm.addEventListener('submit', (event) => {
    event.preventDefault(); 
}
```

- For each `input` field, the code first gets the input value and trims any whitespace. It then gets the corresponding `errorMessage` div and input element using the `querySelector` method. If the input value is empty, the code sets the error message to a relevant message and applies the error class to the parent `formDetails` div. If the input value is not empty, the code clears the error message and applies the success class to the parent `formDetails` div.


```
const name = myForm.elements.name.value.trim();
const nameError = document.querySelector('#name + .errorMessage');
const nameInput = document.getElementById('name');
if (name === '') {
    nameError.textContent = 'Name is required.';
      nameInput.parentNode.classList.add('error');
      nameInput.parentNode.classList.remove('success');
    } else {
      nameError.textContent = '';
      nameInput.parentNode.classList.add('success');
      nameInput.parentNode.classList.remove('error');
    }
```

- For the email input field, the code also checks if the email is in a valid format using a regular expression. If the email is invalid, the code sets the error message to a relevant message and applies the error class to the parent `formDetails` div.


```
const email = myForm.elements.email.value.trim();
    const emailError = document.querySelector('#email + .errorMessage');
    const emailInput = document.getElementById('email');
    if (email === '') {
      emailError.textContent = 'Email is required.';
      emailInput.parentNode.classList.add('error');
      emailInput.parentNode.classList.remove('success');
    } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      emailError.textContent = 'Please enter a valid email address.';
      emailInput.parentNode.classList.add('error');
      emailInput.parentNode.classList.remove('success');
    } else {
      emailError.textContent = '';
      emailInput.parentNode.classList.add('success');
      emailInput.parentNode.classList.remove('error');
    }
```

- For the password input field, the code also checks if the password is at least 8 characters long. If the password is less than 8 characters, the code sets the error message to a relevant message and applies the error class to the parent `formDetails` div.


```
const password = myForm.elements.password.value.trim();
    const passwordError = document.querySelector('#password + .errorMessage');
    const passwordInput = document.getElementById('password');
    if (password === '') {
      passwordError.textContent = 'Password is required.';
      passwordInput.parentNode.classList.add('error');
      passwordInput.parentNode.classList.remove('success');
    } else if (password.length < 8) {
      passwordError.textContent = 'Password is expected to be 8 characters.';
      passwordInput.parentNode.classList.add('error');
      passwordInput.parentNode.classList.remove('success');
    } else {
      passwordError.textContent = '';
      passwordInput.parentNode.classList.add('success');
      passwordInput.parentNode.classList.remove('error');
    }
```

- For the confirm password input field, the code also checks if the confirm password matches the password. If the `confirm` password does not match, the code sets the error message to a relevant message and applies the error class to the parent `formDetails` div.


```
const confirmPassword = myForm.elements.confirmpassword.value.trim();
    const confirmPasswordError = document.querySelector('#confirmPassword + .errorMessage');
    const confirmPasswordInput = document.getElementById('confirmPassword');
    if (confirmPassword === '') {
      confirmPasswordError.textContent = 'Confirm Password is required.';
      confirmPasswordInput.parentNode.classList.add('error');
      confirmPasswordInput.parentNode.classList.remove('success');
    } else if (confirmPassword !== password) {
      confirmPasswordError.textContent = 'Passwords do not match.';
      confirmPasswordInput.parentNode.classList.add('error');
      confirmPasswordInput.parentNode.classList.remove('success');
    } else {
      confirmPasswordError.textContent = '';
      confirmPasswordInput.parentNode.classList.add('success');
      confirmPasswordInput.parentNode.classList.remove('error');
    }
```

- In the final step, the code checks if there are any error messages displayed. If there are no error messages, the code submits the form. Otherwise, it prevents the form from submitting.


  

```
if (nameError.textContent === '' && emailError.textContent === '' && passwordError.textContent === '' && confirmPasswordError.textContent === '') {
        myForm.submit();
      }
    });
```

## The Final Result
[Check it out on Codepen
](https://codepen.io/Tracy4work/pen/BaqGgqm?editors=1000)


If you found this article helpful, please ensure you follow for more helpful posts. I would also appreciate your ideas on what you would be interested in learning,