DEV Community

Cover image for Simple HTML, TAILWINDCSS & Javascript Form Validation
Elvis Sautet
Elvis Sautet

Posted on

Simple HTML, TAILWINDCSS & Javascript Form Validation

In this simple tutorial, i am going to share a complete guide in creating a simple advanced validation form.

Why did i use JS/Why i do

I love using javascript alot since am a full stack web developer. I only use it in any type of application developemnt and it just works like magic to me.
I recenly started using tailwindcss but in this tutorial, i did not take my time working on so much styling but the code on my github account will be updated and added more functionalities as time goes by.

The Html code:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.tailwindcss.com"></script>

    <link rel="stylesheet" href="./index.css">
    <title>FORM VALIDATION</title>
  </head>
  <body>
    <div
      class="min-h-screen bg-slate-900 min-h-screen flex items-center justify-center"
    >
      <div
        class="backdrop-blur-sm bg-white/80 p-5 max-w-md w-full rounded-md shadow-white/10 shadow-sm"
      >
        <form
        id="login"
          class="text-black text-md flex flex-col space-y-3"
          autocomplete="off"
        >
          <div class="flex flex-col w-full space-y-3 tracking-wide">
            <label class="text-lg tracking-wide font-mono" 
            for="firstName"></label>
              First Name</label
            >
            <input
              type="text"
              name="firstName"
              id="firstName"
              class="border-2 firstName w-full p-2 rounded-lg focus:outine-none focus:outline-none"
              autocomplete="off"
              aria-autocomplete="off"
            />
            <span class="block firstNameError text-red-500 text-xs hidden">error</span>
          </div>
          <div lass="flex flex-col w-full space-y-3 tracking-wide">
            <label class="text-lg tracking-wide font-mono" for="firstName">
              Last Name</label
            >
            <input
              type="text"
              name="lastName"
              id="lastName"
              class="border-2 lastName w-full p-2 rounded-lg focus:outine-none focus:outline-none"
              autocomplete="off"
            />
            <span class="block lastNameError text-red-500 text-xs hidden">error</span>
          </div>
          <div lass="flex flex-col w-full space-y-3 tracking-wide">
            <label  class="text-lg tracking-wide font-mono" for="email"> Your Email</label>
            <input
              type="text"
              name="email"
              id="email"
              class="border-2 email w-full p-2 rounded-lg focus:outine-none focus:outline-none"
              autocomplete="off"
            />
            <span class="block emailError text-red-500 text-xs  hidden">error</span>
          </div>
          <div class="">
            <input value="Login Now" type="submit" id="btn" class="px-4 py-3 mt-5 rounded-md bg-slate-600 w-full text-white tracking-wide transition-all duration-300 ease-in-out hover:bg-slate-900 
            cursor-pointer disabled:cursor-not-allowed disabled:opacity-20"/>

          </div>
        </form>
      </div>
    </div>
        <script  src="./index.js"></script>

  </body>
</html>

Enter fullscreen mode Exit fullscreen mode

The Javascript Code:

const firstNameInput = document.getElementById("firstName");
const lastNameInput = document.getElementById("lastName");
const emailInput = document.getElementById("email");
const buttonSubmit = document.getElementById("btn");
const form = document.getElementById("login");
const firstNameError = document.getElementsByClassName("firstNameError")[0];
const lastNameError = document.getElementsByClassName("lastNameError")[0];
const emailError = document.getElementsByClassName("emailError")[0];

//define and declare and empty errors object
let error = {};

/* This is a JavaScript event listener. It is a way to listen for an event. In this case, it is
listening for the form to be submitted. */
form.addEventListener("submit", function (e) {
  e.preventDefault();
//function to validate the form fields before submitting
  checkEmpty();
});

// validate empty fields and set error object
function checkEmpty() {
  //loop and remove all key and value fields in the errors object
  for (let key in error) {
    delete error[key];
  }
  //set all in firstname, lastname, email spans to display none
  firstNameError.style.display = "none";
  lastNameError.style.display = "none";
  emailError.style.display = "none";

  //remove all the error class "border-red-500 classes"
  firstNameInput.classList.remove("border-red-500");
  lastNameInput.classList.remove("border-red-500");
  emailInput.classList.remove("border-red-500");

//remove white spaces from every input Field
  const firstNameValue = firstNameInput.value.trim();
  const lastNameValue = lastNameInput.value.trim();
  const emailValue = emailInput.value.trim();

  //check if all inputs are empty then add new new error keys to the defined error object
  if (firstNameValue === "") {
    error.firstName = "First Name is required";
  }
  if (lastNameValue === "") {
    error.lastName = "Last Name is required";
  }
  if (emailValue === "") {
    error.email = "Email is required";
  }

  //validate the inputs firstName and lastName
  if (firstNameValue !== "") {
    if (!firstNameValue.match(/^[a-zA-Z0-9]+$/)) {
      error.firstName = "First Name must be letters only";
    }
  }
  if (lastNameValue !== "") {
    if (!lastNameValue.match(/^[a-zA-Z0-9]+$/)) {
      error.lastName = "Last Name must be letters only";
    }
  }
  if (emailValue !== "") {
    //validating an email
    if (!emailValue.match(/^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/)) {
      error.email = "Email must be a valid email";
    }
  }

  //if we have error add the error to the error message
  if (Object.keys(error).length > 0) {
    displayError();
  } else {
    //submit the form with a delay of 2 seconds
    //change the button innerText to submitting and add no-cursor class and disabled attribute to it
    buttonSubmit.value = "Submitting...";
    buttonSubmit.setAttribute("disabled", "disabled");

//set a delay of 2 seconds since we dont have an api endpoint to send the data to just mimic the process
    new Promise(function (resolve, reject) {
      setTimeout(function () {
        resolve(submitForm());
      }, 2000);
    });
  }
}

//display errors respectivey to the span html classes
function displayError() {
  //set all errors to their respectivey and also changing hidden 
error containers to be a block.
  if (error.firstName) {
    firstNameInput.classList.add("border-red-500");
    firstNameError.style.display = "block";
    firstNameError.innerHTML = error.firstName;
  }
  if (error.lastName) {
    lastNameInput.classList.add("border-red-500");
    lastNameError.style.display = "block";
    lastNameError.innerHTML = error.lastName;
  }
  if (error.email) {
    //loop over the classes and add other classes
    emailInput.classList.add("border-red-500");
    emailError.style.display = "block";
    emailError.innerHTML = error.email;
  }
}

//submitting the form
function submitForm() {
//TODO: Add an API ENDPOINT to send the data.

  //show the values for now but later we going to add some api intergration
  console.log(firstNameInput.value);
  console.log(lastNameInput.value);
  console.log(emailInput.value);
  //reset the login buttonSubmit

//after 2 seconds is over change the input type button innerText and remove the disabled attribute.
  buttonSubmit.value = "Login Now";
  buttonSubmit.removeAttribute("disabled");

  //reset the form and clear all fields
  form.reset();
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)