DEV Community

Dicky Saputra
Dicky Saputra

Posted on

Simple validation with Javascript & JQuery

Form validation is an essential aspect of web development that ensures users provide the correct and expected input before submitting a form. Implementing validation on the frontend improves user experience by providing immediate feedback and reducing the need for server-side validation alone. Here's a step-by-step guide on how to set up frontend validation for a form.

Step 1: Wrap the Form with a <form> Tag and Add novalidate Attribute

The first step is to create your form structure in HTML and add the novalidate attribute. This attribute disables the browser's default validation, allowing you to implement custom validation.

<form action="" class="Form js-form" method="POST" novalidate>
  <div class="Form__Field ">
    <label for="locationsingle-question_type"
      >Location type: <span>*</span></label
    >
    <select
      name="locationsingle-question_type"
      id="locationsingle-question_type"
      class="js-select2"
      required
    >
      <option value="Trainingen">Trainingen</option>
      <option value="Lidmaatschap">Lidmaatschap</option>
      <option value="Reserveren">Reserveren</option>
      <option value="Vrijwilligers">Vrijwilligers</option>
      <option value="Sponsoring">Sponsoring</option>
      <option value="Overige">Overige</option>
    </select>
    <span class="body-text-sm-medium primary-500 Form__Field__HelperText"
      >veld vraag type niet geldig</span
    >
  </div>

  <div class="Form__Field Form__Field--50">
    <label for="locationsingle-email">Email<span>*</span></label>
    <input
      id="locationsingle-email"
      name="locationsingle-email"
      type="email"
      placeholder="email@gmail.com"
      required
    />
    <span class="body-text-sm-medium primary-500 Form__Field__HelperText"
      >veld email niet geldig</span
    >
  </div>

  <div class="Stack Stack--JustifyCenter w-100">
    <button type="submit" class="Button Button--Primary Button--Xl">
      Submit
    </button>
  </div>
</form>
Enter fullscreen mode Exit fullscreen mode

Note: make sure your structure field is like this:

-field wrapper [Form__Field]
-- label (optional)
-- input
-- helper text [Form__Field__HelperText]
Enter fullscreen mode Exit fullscreen mode

Step 2: Styling the Form and Invalid State

Next, let's add some CSS to style the form and the error messages. We'll also style the invalid state of the input fields

@use "/assets/css/src/abstracts/typo-mixins" as t;
@use "/assets/css/src/abstracts/variables" as v;
@use "/assets/css/src/abstracts/mixins" as m;

.Form {
    ...

    &.Form--Validated {
        ...
    }

    &__Field {
        ...

        &__HelperText {
            display: none;
        }


        label {
            ...
        }

        input,
        textarea,
        select {
            ...

            &:focus {
                ...
            }

            &:disabled,
            &.disabled,
            &:read-only {
                ...
            }

            &:invalid,
            &.invalid {
                ~ .Form__Field__HelperText {
                    .Form--Validated & {
                        display: inline;
                    }
                }
            }
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Write JavaScript to Handle Validation and Add Additional Rules

Now, let's write the JavaScript to handle the validation. This script will check the form fields, display error messages, and prevent form submission if there are validation errors.

import $ from "jquery";
import { emailRules, floatRules, phoneNumberRules } from "../abstract/regex";

const componentsForm = () => {
  const init = () => {
    execute();
  };

  const execute = () => {
    const el = {
      main: ".js-form",
      btnOpenFile: ".js-button-open-file",
    };
    if ($(el.main).length === 0) return;

    $(document).on("submit", el.main, function (e) {
      const form = e.target;

      const input = $(this).find(`input`);

      let isValid = {};
      input.each(function () {
        const type = $(this).attr("type");
        const c_type = $(this).data("type");
        const isRequired = $(this).prop("required");
        const isDisabled = $(this).prop("disabled");

        if (isDisabled) return;

        const value = $(this).val();
        const id = $(this).attr("id");

        const handleCondition = (condition) => {
          if (condition) {
            isValid[id] = "invalid";
          } else {
            delete isValid[id];
          }
        };

        switch (c_type) {
          case "float":
            handleCondition(!floatRules.test(value));
            break;

          default:
            break;
        }

        switch (type) {
          case "email":
            handleCondition(!emailRules.test(value));
            break;
          case "tel":
            handleCondition(!phoneNumberRules.test(value) && value !== "");
            break;
          case "file":
            if (isRequired)
              handleCondition(!this.files || this.files.length === 0);
            break;

          default:
            break;
        }
      });

      if (!form.checkValidity() || Object.values(isValid).length > 0) {
        e.preventDefault();
        e.stopPropagation();
      }

      form.classList.add("Form--Validated");
    });

    $(document).on(
      "input",
      `${el.main} input, ${el.main} select, ${el.main} textarea`,
      function () {
        const c_type = $(this).data("type");
        const type = $(this).attr("type");
        const value = $(this).val();

        const handleCondition = (condition) => {
          if (condition) {
            $(this).addClass("invalid");
          } else {
            $(this).removeClass("invalid");
          }
        };

        switch (c_type) {
          case "float":
            handleCondition(!floatRules.test(value));
            break;

          default:
            break;
        }

        switch (type) {
          case "email":
            handleCondition(!emailRules.test(value));
            break;
          case "tel":
            handleCondition(!phoneNumberRules.test(value) && value !== "");
            break;

          default:
            break;
        }
      },
    );
  };
  init();
};

try {
  componentsForm();
} catch (error) {
  console.error("componentsForm", error);
}
Enter fullscreen mode Exit fullscreen mode

How to use it

Basic

You can use it like you use HTML's built-in validation, such as involving type, required, etc

Custom validation

  • You can add a data-type attribute to the input. like code below
<input
  id="locationsingle-email"
  name="locationsingle-email"
  type="text"
  data-type="float"
  placeholder="email@gmail.com"
  required
/>
Enter fullscreen mode Exit fullscreen mode
  • then you can write rules in javascript according to your wishes. in this case I use regex to write the rules
const floatRules = /^\d+(\.\d+)?$/;
// edit the js on this part

$(document).on("submit", el.main, function (e) {
   ...
  switch (c_type) {
    case "float":
      handleCondition(!floatRules.test(value));
      break;

    default:
      break;
  }
  ...
});

$(document).on(
  "input",
  `${el.main} input, ${el.main} select, ${el.main} textarea`,
  function () {
    ...
    switch (c_type) {
      case "float":
        handleCondition(!floatRules.test(value));
        break;

      default:
        break;
    }
    ...
  }
);
Enter fullscreen mode Exit fullscreen mode

Conclusion

Implementing frontend validation enhances user experience by providing immediate feedback and reducing errors before data reaches the server. By following these steps—wrapping the form with a form tag and adding the novalidate (novalidate will deactive validation default. and we override via javascript) attribute, styling the form and its invalid state, and writing JavaScript to handle validation—you can create robust and user-friendly forms. This approach ensures users provide the correct input, ultimately leading to better data quality and smoother interactions.

Top comments (0)