Form Validation in Bootstrap 5.3


In Bootstrap 5.3, form validation is a powerful feature that allows you to validate user input and provide visual feedback to indicate whether the input is valid or not. Form validation can be implemented on the client-side using Bootstrap's built-in classes and JavaScript, providing a seamless user experience. Here's an explanation of form validation in Bootstrap 5.3



Client-side Validation:

Bootstrap 5.3 offers a range of CSS classes to facilitate client-side form validation. These classes are applied to form elements to indicate their validation state. The main classes are

  • .is-valid: Applied to indicate valid input.
  • .is-invalid: Applied to indicate invalid input.

Additionally, Bootstrap provides validation styles for feedback messages associated with form controls:

  • .valid-feedback: Applied to provide feedback for valid input.
  • .invalid-feedback:Applied to provide feedback for invalid input.

Required Fields:

Bootstrap 5.3 offers a range of CSS classes to facilitate client-side form validation. These classes are applied to form elements to indicate their validation state. The main classes are

Form Validation Classes:

Bootstrap 5.3 introduces new form validation classes that can be applied to form elements to trigger validation styling. These classes are:

  • .form-control: Applied to form inputs for styling and consistent appearance.
  • .form-check-input: Applied to checkboxes and radio buttons.
  • .form-select: Applied to select elements for dropdowns.

Custom Validation:

Bootstrap 5.3 allows you to implement custom validation by adding the data-bs-validation attribute to form elements. You can define your own validation logic using JavaScript and apply custom validation styles accordingly.

Validation Feedback:

Bootstrap provides the .form-control-feedback class to display icons or other indicators of validation status alongside form controls.

Example

<!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" />
    <title>Student Registration Form</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" />
    <link rel="stylesheet" href="css/base.css" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" />
  </head>
  <body>
    <div class="container mt-5">
      <div class="row">
        <!--Row Start-->

        <div class="offset-lg-3 offset-md-1 col-lg-6 col-md-10">
          <h6 class="fw-semibold fs-5 text-uppercase text-primary">Student Registration Form</h6>
          <div class="bg-primary bg-opacity-10 my-4 p-3 d-flex align-items-center justify-content-between rounded">
            <span class="fw-semibold">Basic Information</span>
            <i class="bi bi-bookmark-fill text-secondary fs-5"></i>
          </div>

          <form id="myForm" novalidate>
            <div class="mb-3">
              <label for="name" class="form-label">Name</label>
              <input type="text" class="form-control" id="name" required placeholder="Enter Full Name" />
              <div class="invalid-feedback">Please enter your name.</div>
            </div>
            <div class="mb-3">
              <label class="form-label">Gender</label>
              <div class="d-flex">
                <div class="form-check me-3">
                  <input class="form-check-input" type="radio" name="gender" id="male" checked required />
                  <label class="form-check-label" for="male"> Male </label>
                </div>
                <div class="form-check me-3">
                  <input class="form-check-input" type="radio" name="gender" id="female" />
                  <label class="form-check-label" for="female"> Female </label>
                </div>
              </div>
              <div class="invalid-feedback" id="gender-error">Please select your gender.</div>
            </div>

            <div class="mb-3">
              <label for="email" class="form-label">Email</label>
              <input type="email" class="form-control" id="email" required placeholder="Enter Email Address" />
              <div class="invalid-feedback">Please enter a valid email address.</div>
            </div>

            <div class="row mb-3">
              <div class="col-md-6">
                <label for="password" class="form-label">Password</label>
                <input type="password" class="form-control" id="password" required placeholder="Enter Password" />
                <div class="invalid-feedback">Please enter a password.</div>
              </div>
              <div class="col-md-6">
                <label for="confirmPassword" class="form-label">Confirm Password</label>
                <input type="password" class="form-control" id="confirmPassword" required placeholder="Enter Confirm Password" />
                <div class="invalid-feedback">Passwords do not match.</div>
              </div>
            </div>

            <div class="bg-info bg-opacity-10 my-4 p-3 d-flex align-items-center justify-content-between rounded">
              <span class="fw-semibold">Contact Information</span>
              <i class="bi bi-phone-fill text-secondary fs-5"></i>
            </div>

            <div class="mb-3">
              <label for="phone" class="form-label">Phone Number</label>
              <input type="text" class="form-control" id="phone" required pattern="[0-9]{10}" placeholder="Enter Phone Number" />
              <div class="invalid-feedback">Please enter a valid 10-digit phone number.</div>
            </div>

            <div class="mb-3">
              <label for="address" class="form-label">Address</label>
              <textarea class="form-control" id="address" required placeholder="Enter Complete Address"></textarea>
              <div class="invalid-feedback">Please enter your address.</div>
            </div>

            <div class="row mb-3">
              <div class="col-md-6">
                <label for="city" class="form-label">City</label>
                <select class="form-select" id="city" required>
                  <option value="">Select a City</option>
                  <option value="Salem">Salem</option>
                  <option value="Chennai">Chennai</option>
                  <option value="Hosur">Hosur</option>
                </select>
                <div class="invalid-feedback">Please select a City.</div>
              </div>

              <div class="col-md-6">
                <label for="pincode" class="form-label">Pincode</label>
                <input type="text" class="form-control" id="pincode" required placeholder="Enter Pincode" />
                <div class="invalid-feedback">Please enter a valid pincode.</div>
              </div>
            </div>

            <div class="bg-warning bg-opacity-10 my-4 p-3 d-flex align-items-center justify-content-between rounded">
              <span class="fw-semibold">Other Information</span>
              <i class="bi bi-book-fill text-secondary fs-5"></i>
            </div>

            <div class="row mb-3">
              <div class="col-md-6">
                <label for="startDate" class="form-label">Start Date</label>
                <input type="date" class="form-control" id="startDate" required />
                <div class="invalid-feedback">Start date must be before the end date.</div>
              </div>
              <div class="col-md-6">
                <label for="endDate" class="form-label">End Date</label>
                <input type="date" class="form-control" id="endDate" required />
                <div class="invalid-feedback">End date must be after the start date.</div>
              </div>
            </div>

            <div class="mb-3 form-check">
              <input type="checkbox" class="form-check-input" id="agree" required />
              <label class="form-check-label" for="agree">I agree to the terms and conditions</label>
              <div class="invalid-feedback">You must agree to the terms and conditions.</div>
            </div>
            <div class="mb-3 d-flex justify-content-end">
              <button type="submit" class="btn btn-primary me-2">Register Now</button>
              <button type="reset" class="btn btn-danger">Clear Details</button>
            </div>
          </form>
        </div>

        <!--Row End-->
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>

    <script>
      (function () {
        "use strict";
        var form = document.getElementById("myForm");

        form.addEventListener("submit", function (event) {
          if (!form.checkValidity()) {
            event.preventDefault();
            event.stopPropagation();
          }

          // Password validation
          let passwordInput = document.getElementById("password");
          let confirmPasswordInput = document.getElementById("confirmPassword");
          if (passwordInput.value && confirmPasswordInput.value !== passwordInput.value) {
            confirmPasswordInput.setCustomValidity("Passwords do not match.");
          } else {
            confirmPasswordInput.setCustomValidity("");
          }

          //Phone Validation
          let phoneInput = document.getElementById("phone");
          let phoneRegex = /^[0-9]{10}$/;
          if (!phoneRegex.test(phoneInput.value)) {
            phoneInput.setCustomValidity("Please enter a valid 10-digit phone number.");
          } else {
            phoneInput.setCustomValidity("");
          }

          //Pincode Validation
          let pincodeInput = document.getElementById("pincode");
          let pinRegex = /^\d{6}$/;
          if (!pinRegex.test(pincodeInput.value)) {
            pincodeInput.setCustomValidity("Please enter a valid pincode.");
          } else {
            pincodeInput.setCustomValidity("");
          }

          // Custom validation for start and end dates
          let startDateInput = document.getElementById("startDate");
          let endDateInput = document.getElementById("endDate");
          let startDate = new Date(startDateInput.value);
          let endDate = new Date(endDateInput.value);

          if (startDate >= endDate) {
            startDateInput.setCustomValidity("Start date must be before the end date.");
            endDateInput.setCustomValidity("End date must be after the start date.");
          } else {
            startDateInput.setCustomValidity("");
            endDateInput.setCustomValidity("");
          }

          // Custom validation for select field
          var cityInput = document.getElementById("city");
          if (cityInput.value === "") {
            cityInput.setCustomValidity("Please select a city.");
          } else {
            cityInput.setCustomValidity("");
          }

          form.classList.add("was-validated");
        });
      })();
    </script>
  </body>
</html>

Event Listener:

The code starts by adding an event listener to the form element with the ID "myForm". The event being listened to is the "submit" event, which is triggered when the user tries to submit the form.

Form Validation:

Inside the event listener, the code first checks if the form is valid using the form.checkValidity() method. If the form is not valid, the event's default behavior is prevented, and further propagation of the event is stopped.

Password Validation:

The code performs password validation by comparing the values of the password and confirmPassword input fields. If the passwords do not match, the setCustomValidity() method is called on the confirmPassword input element, setting a custom error message. Otherwise, the custom validity is cleared.

Phone Validation:

Phone number validation is performed using a regular expression (phoneRegex). The code checks if the phone number input value matches the regular expression. If it doesn't, the setCustomValidity() method is called on the phoneInput element to set a custom error message.

Pincode Validation:

Similar to phone validation, pincode validation is performed using a regular expression (pinRegex). The code checks if the pincode input value matches the regular expression. If it doesn't, the setCustomValidity() method is called on the pincodeInput element to set a custom error message.

Custom Date Validation:

The code performs custom validation for start and end dates. It compares the values of the startDate and endDate input fields, converting them into Date objects. If the start date is not before the end date, error messages are set using the setCustomValidity() method on both input fields.

Custom Validation for Select Field:

The code checks if a city has been selected in the select field with the ID "city". If no city is selected (i.e., the value is empty), a custom error message is set using the setCustomValidity() method.

Adding Validation Classes:

After performing all the validations, the code adds the "was-validated" class to the form element. This class is part of Bootstrap and triggers the display of validation styles and messages defined in the CSS.

Live Preview

By leveraging these features, you can easily implement form validation in Bootstrap 5.3, improving the user experience by providing visual feedback and ensuring the correctness of user input before form submission. Remember, while client-side validation is helpful for immediate feedback, server-side validation is still crucial to ensure data integrity and security.