Bootstrap - Validation



This chapter will discuss about Bootstrap validation. Bootstrap 5 Validation enhances HTML5 form validation by offering useful feedback to users, supporting default browser behavior, custom styles, and JavaScript.

The client-side custom validation styles and tooltips are inaccessible because they are not visible to assistive technology. It is recommended to use either the server-side option or the default browser validation technique, while we work on the solution.

How form validation works in Bootstrap

  • The two pseudo-classes :invalid and :valid in CSS are used to provide HTML form validation. It applies to the <textarea>, <select>, and <input> elements.

  • Bootstrap applies the :invalid and :valid styles to the parent .was-validated class. Fields without a value show as invalid when the page loads. You choose when to activate them (usually after a form submission).

  • To restore the original appearance of the form after dynamic submissions using Ajax, the class .was-validated should be removed from the <form> to reset its appearance.

  • The pseudo-classes can be replaced with the .is-invalid and .is-valid classes for server-side validation as a fallback, without the need for a .was-validated parent class.

  • Currently, CSS limitations prevent us from directly applying styles to a <label> element that precedes a form control in the DOM without the help of custom JavaScript.

  • The constraint validation API, which consists of various JavaScript methods for validating form controls, is supported by all contemporary web browsers.

  • Use browser default styles or create custom feedback styles using HTML/CSS.

  • Use setCustomValidity method in JavaScript for unique validity messages.

Let's look at some examples of custom form validation styles, optional server-side classes and browser defaults.

Custom styles

  • Add novalidate boolean attribute to the <form> to receive custom validation messages from Bootstrap.

  • Browser default feedback tooltips are disabled with above boolean attribute but JavaScript validation APIs still work. Submitting this form will trigger JavaScript to provide feedback, displaying :invalid and :valid styles on form controls.

  • Custom feedback styles improve feedback communication by adding colors, borders, focus styles, and backdrop icons. Backdrop icons for <select> are only available for .form-select, and not .form-control.

This example demonstrates a Bootstrap form with validation features, to ensure that the required fields are filled out correctly before the form can be submitted.

Example

You can edit and try running this code using Edit & Run option.

  <!DOCTYPE html>
  <html lang="en">
  <head>
   <title>Bootstrap - Validation</title>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
   <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
  </head>
  <body>
   <form class="row g-3 needs-validation" novalidate>
     <div class="col-md-4">
       <label for="validationCustomName" class="form-label">Full Name</label>
       <input type="text" class="form-control" id="validationCustomName" value="Jhon Miller" required>
       <div class="invalid-feedback">
           Correct input!
       </div>
     </div>

     <div class="col-md-4">
       <label for="validationCustomEmail" class="form-label">Email Id</label>
       <div class="input-group has-validation">
         <input type="text" class="form-control" id="validationCustomEmail" aria-describedby="inputGroupPrepend" required>
         <span class="input-group-text" id="inputGroupPrepend">@tutorialspoint.com</span>
         <div class="invalid-feedback">
            Please enter correct mail id.
         </div>
       </div>
     </div>

     <div class="col-md-4">
       <label for="validationCustomPhone" class="form-label">Mobile no</label>
       <input type="text" class="form-control" id="validationCustomPhone" required>
       <div class="invalid-feedback">
          please enter correct mobile no.
       </div>
     </div>

     <div class="col-md-6">
       <label for="validationAddress" class="form-label">Address</label>
         <input type="text" class="form-control" id="validationAddress" value="XYZ - 123" required>
         <div class="valid-feedback">
          Correct input!
         </div>
       </div>
     </div>

     <div class="col-md-3">
       <label for="validationCustom" class="form-label">Gender</label>
       <select class="form-select" id="validationCustom" required>
         <option selected disabled value="">Choose...</option>
         <option>Male</option>
         <option>Female</option>
         <option>Others</option>
       </select>
       <div class="invalid-feedback">
          Please select gender.
       </div>
     </div>

     <div class="col-12">
       <div class="form-check">
         <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
         <label class="form-check-label" for="invalidCheck">
            I have reviewed and agree to Terms of Services and Privacy Policy.
         </label>
         <div class="invalid-feedback">
            You must agree before submitting.
         </div>
       </div>
     </div>

     <div class="col-12">
       <button class="btn btn-primary" type="submit">Submit</button>
     </div>
   </form>
  <script>
    (() => {
    'use strict'

    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    const forms = document.querySelectorAll('.needs-validation')

    // Loop over them and prevent submission
    Array.from(forms).forEach(form => {
      form.addEventListener('submit', event => {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
  })()
  </script>
  </body>
  </html>

The following JavaScript code snippet disables form submissions if there are invalid fields. It achieves this by adding event listeners to the forms and preventing the default form submission behavior if the form is not valid.


    // Example JavaScript starter for disabling form submissions if there are invalid fields
    (() => {
      'use strict'

      // Fetch all the forms we want to apply custom Bootstrap validation styles to
      const forms = document.querySelectorAll('.needs-validation')

      // Loop over them and prevent submission
      Array.from(forms).forEach(form => {
        form.addEventListener('submit', event => {
          if (!form.checkValidity()) {
            event.preventDefault()
            event.stopPropagation()
          }

          form.classList.add('was-validated')
        }, false)
      })
    })()

Browser defaults

  • We can also use browser default messages instead of custom validation message. Depending on your browser and OS, feedback style varies slightly.

  • Although CSS cannot be used to style these feedback styles, JavaScript can still be used to alter the feedback text.

Try submitting the form in the following example to how default browser validation messages show up.

Example

You can edit and try running this code using Edit & Run option.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bootstrap Form - Validation</title>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
    </head>
    <body>
      <form class="row g-3">
        <div class="col-md-4">
          <label for="validationDefaultName" class="form-label">Full Name</label>
          <input type="text" class="form-control" id="validationDefaultName" value="name" required>
        </div>
        <div class="col-md-4">
          <label for="validationDefaultEmail" class="form-label">Email Id</label>
          <div class="input-group">
            <input type="text" class="form-control" id="validationDefaultEmail" aria-describedby="inputGroupPrepend" required>
            <span class="input-group-text" id="inputGroupPrepend">@tutorialspoint.com</span>
          </div>
        </div>
        <div class="col-md-4">
          <label for="validationDefaultMob" class="form-label">Mobile No</label>
          <input type="text" class="form-control" id="validationDefaultMob" value="" required>
        </div>
        <div class="col-md-6">
          <label for="validationDefaultAddress" class="form-label">Address</label>
          <input type="text" class="form-control" id="validationDefaultAddress" required>
        </div>
        <div class="col-md-3">
          <label for="validationDefaultGender" class="form-label">Gender</label>
          <select class="form-select" id="validationDefaultGender" required>
            <option selected disabled value="">Choose...</option>
            <option>Male</option>
            <option>Female</option>
            <option>Others</option>
          </select>
        </div>
        <div class="form-check">
            <input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
            <label class="form-check-label" for="invalidCheck2">
              I have reviewed and agree to Terms of Services and Privacy Policy.
            </label>
          </div>
        </div>
        <div class="col-12">
          <button class="btn btn-primary" type="submit">Submit</button>
        </div>
      </form>
    </body>
    </html>

Server-side

  • Client-side validation is recommended, but in case of server-side validation, use .is-invalid and .is-valid directives to indicate form field status. Also consider using .invalid-feedback with these classes.

  • Use aria-describedby attribute to link invalid feedback/error message to the form field in the case of invalid fields. (Allows more than one id to be referenced if field connects to other form text.)

  • Input groups need an additional .has-validation class for dealing with issues with border radius.

Example

You can edit and try running this code using Edit & Run option.

  <!DOCTYPE html>
  <html lang="en">
  <head>
    <title>Bootstrap - Validation</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
  </head>
  <body>
    <form class="row g-3">
      <div class="col-md-4">
        <label for="validationServerName" class="form-label">Full name</label>
        <input type="text" class="form-control is-valid" id="validationServerName" value="Mark" required>
        <div class="valid-feedback">
          enter your name
        </div>
      </div>
      <div class="col-md-4">
        <label for="validationServerEmail" class="form-label">Email Id</label>
        <div class="input-group has-validation">
          <input type="text" class="form-control is-invalid" id="validationServerEmail"
            aria-describedby="inputGroupPrepend3 validationServerEmailFeedback" required>
          <span class="input-group-text" id="inputGroupPrepend3">@tutorialspoint.com</span>
          <div id="validationServerEmailFeedback" class="invalid-feedback">
            Please enter mail id.
          </div>
        </div>
      </div>
      <div class="col-md-4">
        <label for="validationServerMob" class="form-label">Mobile no</label>
        <input type="text" class="form-control is-valid" id="validationServerMob" value="" required>
        <div class="valid-feedback">
          Please enter mobile no
        </div>
      </div>
      <div class="col-md-6">
        <label for="validationServerAddress" class="form-label">Address</label>
        <input type="text" class="form-control is-invalid" id="validationServerAddress"
          aria-describedby="validationServerAddressFeedback" required>
        <div id="validationServerAddressFeedback" class="invalid-feedback">
          Please enter a valid Address.
        </div>
      </div>
      <div class="col-md-3">
        <label for="validationServer04" class="form-label">Gender</label>
        <select class="form-select is-invalid" id="validationServer04" aria-describedby="validationServer04Feedback"
          required>
          <option selected disabled value="">Choose...</option>
          <option>Male</option>
          <option>Female</option>
          <option>Others</option>
        </select>
        <div id="validationServer04Feedback" class="invalid-feedback">
          Please select a valid gender.
        </div>
      </div>
      <div class="col-12">
        <div class="form-check">
          <input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheckPolicy"
            aria-describedby="invalidCheckFeedback" required>
          <label class="form-check-label" for="invalidCheckPolicy">
            I have reviewed and agree to Terms of Services and Privacy Policy.
          </label>
          <div id="invalidCheckFeedback" class="invalid-feedback">
            You must agree before submitting.
          </div>
        </div>
      </div>
      <div class="col-12">
        <button class="btn btn-primary" type="submit">Submit</button>
      </div>
    </form>
  </body>
  </html>;

Supported elements

The following form controls and components support validation styles:

  • <textarea> and <input> using the .form-control (allowing input groups to contain up to one .form-control).

  • <select> using .form-select

  • .form-check

Example

You can edit and try running this code using Edit & Run option.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bootstrap Form - Validation</title>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
    </head>
    <body>
      <form class="was-validated">
        <div class="mb-3">
          <label for="validationTextarea" class="form-label">Add comment</label>
          <textarea class="form-control" id="validationTextarea" placeholder="Comment Here" required></textarea>
          <div class="invalid-feedback">
            Add comment
          </div>
        </div>
        <div class="form-check mb-3">
          <input type="checkbox" class="form-check-input" id="validationFormCheck" required>
          <label class="form-check-label" for="validationFormCheck">Item One</label>
          <div class="invalid-feedback">Invalid Answer</div>
        </div>
        <div class="form-check">
          <input type="radio" class="form-check-input" id="validationFormRadio1" name="radio-stacked" required>
          <label class="form-check-label" for="validationFormRadio1">Item Two</label>
        </div>
        <div class="form-check mb-3">
          <input type="radio" class="form-check-input" id="validationFormRadio2" name="radio-stacked" required>
          <label class="form-check-label" for="validationFormRadio2">Item Three</label>
          <div class="invalid-feedback">Invalid Answer</div>
        </div>
        <div class="mb-3">
          <select class="form-select" required aria-label="select example">
            <option value="">Gender</option>
            <option value="1">Male</option>
            <option value="2">Female</option>
            <option value="3">Others</option>
          </select>
          <div class="invalid-feedback">Invalid selection</div>
        </div>
        <div class="mb-3">
          <input type="file" class="form-control" aria-label="file example" required>
          <div class="invalid-feedback">File size more than 256kb</div>
        </div>
        <div class="mb-3">
          <button class="btn btn-primary" type="submit" disabled>Submit</button>
        </div>
      </form>
    </body>
    </html>

Tooltips

  • To display validation feedback in a styled tooltip, swap the classes .{valid|invalid}-feedback for .{valid|invalid}-tooltip if the layout permits it.

  • To position the tooltip, make sure the parent has the property position: relative.

Example

You can edit and try running this code using Edit & Run option.

  <!DOCTYPE html>
  <html lang="en">
  <head>
    <title>Bootstrap - Validation</title>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/js/bootstrap.bundle.min.js"></script>
  </head>
  <body>
    <form class="row g-3 needs-validation" novalidate>
      <div class="col-md-4 position-relative">
        <label for="validationTooltipName" class="form-label">Full Name</label>
        <input type="text" class="form-control" id="validationTooltipName" value="Jhon Miller" required>
        <div class="valid-tooltip">
          Correct Input!
        </div>
      </div>
      <div class="col-md-4 position-relative">
        <label for="validationTooltipEmail" class="form-label">Email Id</label>
        <div class="input-group has-validation">
          <input type="text" class="form-control" id="validationTooltipEmail" aria-describedby="validationTooltipEmailPrepend" required>
          <span class="input-group-text" id="validationTooltipEmailPrepend">@tutorialspoint.com</span>
          <div class="invalid-tooltip">
           Please enter mail id.
          </div>
        </div>
      </div>
      <div class="col-md-4 position-relative">
        <label for="validationTooltipMob" class="form-label">Mobile no</label>
        <input type="text" class="form-control" id="validationTooltipMob" required>
        <div class="invalid-tooltip">
          Please enter mobile no.
        </div>
      </div>

      <div class="col-md-6 position-relative">
        <label for="validationTooltipAddress" class="form-label">Address</label>
        <input type="text" class="form-control" id="validationTooltipAddress" value="XYZ - 123" required>
        <div class="valid-tooltip">
         Correct Input!
        </div>
      </div>
      <div class="col-md-3 position-relative">
        <label for="validationTooltip04" class="form-label">Gender</label>
        <select class="form-select" id="validationTooltip04" required>
          <option selected disabled value="">Choose...</option>
          <option>Male</option>
          <option>Female</option>
          <option>Others</option>
        </select>
        <div class="invalid-tooltip">
          Please select a valid gender.
        </div>
      </div>

      </div>
      <div class="col-12">
        <button class="btn btn-primary" type="submit">Submit</button>
      </div>
    </form>
    <script>
      (() => {
    'use strict'

    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    const forms = document.querySelectorAll('.needs-validation')

    // Loop over them and prevent submission
    Array.from(forms).forEach(form => {
      form.addEventListener('submit', event => {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
  })()
    </script>
  </body>
  </html>
Advertisements