Search code examples
javascripthtmlcssformstwitter-bootstrap

Use Bootstrap 5 Form Validation With a Value Length Requirement


I am working on developing a form and I am currently using Bootstrap 5's CSS validation classes with a custom JS file that toggles the class depending on user entry. This is working flawlessly. However, I would like to add a minimum character length requirement that displays the invalid feedback flag until the text contains at least two characters. Currently, it is showing good even if a single character is entered. Here are my HTML and JS files. I am not using any custom CSS at the moment.

HTML

 <div class="container-fluid">
                <div class="row my-10 justify-content-center">
                    <div class="col-md-8">
                        <div class="card page-content-card">
                            <form class="page-form needs-validation" action="" method="post" novalidate>
                                <div class="row">
                                    <div class="col-md-12 page-form-section">
                                        <h4 class="page-form-section-text">Personal Info</h5>
                                    </div>
                                </div>
                                <div class="row pb-4">
                                    <div class="col-md-6">
                                        <div class="form-floating">
                                            <input type="text" class="form-control" id="firstname" name="firstname" placeholder="First Name" required>
                                            <label for="firstname">First Name</label>
                                            <div class="invalid-feedback">
                                                First name must include at least two characters.
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-6">
                                        <div class="form-floating">
                                            <input type="text" class="form-control" id="lastname" placeholder="Last Name" required>
                                            <label for="lastname">Last Name</label>
                                            <div class="invalid-feedback">
                                                Last name must include at least two characters.
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row pb-3">
                                    <div class="col-md-12">
                                        <div class="form-floating has-validation">
                                            <input type="email" class="form-control" id="email" placeholder="Email" required>
                                            <label for="email">Email</label>
                                            <div class="invalid-feedback">
                                                Email address must be in format - [email protected].
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="col-md-12 page-form-section">
                                        <h4 class="page-form-section-text">Profile Information</h5>
                                    </div>
                                </div>
                                <div class="row pb-3">
                                    <div class="col-md-12">
                                        <div class="form-floating">
                                            <input type="text" class="form-control" id="username" placeholder="User Name" required>
                                            <label for="username">User Name</label>
                                            <div class="invalid-feedback">
                                                User name must contain at least five characters.
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row pb-3">
                                    <div class="col-md-12">
                                        <div class="form-floating">
                                            <input type="password" class="form-control" id="password" placeholder="Password" required>
                                            <label for="password">Password</label>
                                            <div class="invalid-feedback">
                                                Password must contain at least seven characters.
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="row pb-3">
                                    <div class="col-md-12">
                                        <div class="form-floating">
                                            <input type="password" class="form-control" id="confirmpassword" placeholder="Confirm Password" required>
                                            <label for="password">Confirm Password</label>
                                        </div>
                                    </div>
                                </div>
                                <div class="row pb-3">
                                    <div class="col-md-12">
                                        <button class="btn btn-warning" type="submit">Submit</button>
                                    </div>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>

JS

(function () {
'use strict'

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

// Loop over them and prevent submission
Array.prototype.slice.call(forms)
    .forEach(function (form) {
    form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
        event.preventDefault()
        event.stopPropagation()
        }

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

})()


Solution

  • Just set the minlength attribute on your inputs.

    As stated in the Bootstrap docs:

    All modern browsers support the constraint validation API, a series of JavaScript methods for validating form controls.

    --https://getbootstrap.com/docs/5.3/forms/validation/

    If you follow that link you will see a method for element.validity.tooShort keep following the links and you find this

    Suffering from being too short


    When a control has a value that is too short for the form control minlength attribute (input minlength, textarea minlength).

    When the setValidity() method sets tooShort flag to true for a form-associated custom element.

    --https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-being-too-short

    (function() {
      'use strict'
    
      // Fetch all the forms we want to apply custom Bootstrap validation styles to
      var forms = document.querySelectorAll('.needs-validation')
    
      // Loop over them and prevent submission
      Array.prototype.slice.call(forms)
        .forEach(function(form) {
          form.addEventListener('submit', function(event) {
            if (!form.checkValidity()) {
              event.preventDefault()
              event.stopPropagation()
            }
    
            form.classList.add('was-validated')
          }, false)
        })
    })()
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
    
    
    <div class="container-fluid">
      <div class="row my-10 justify-content-center">
        <div class="col-md-8">
          <div class="card page-content-card">
            <form class="page-form needs-validation" action="" method="post" novalidate>
              <div class="row">
                <div class="col-md-12 page-form-section">
                  <h4 class="page-form-section-text">Personal Info</h5>
                </div>
              </div>
              <div class="row pb-4">
                <div class="col-md-6">
                  <div class="form-floating">
                    <input type="text" class="form-control" id="firstname" name="firstname" placeholder="First Name" required minlength="2">
                    <label for="firstname">First Name</label>
                    <div class="invalid-feedback">
                      First name must include at least two characters.
                    </div>
                  </div>
                </div>
                <div class="col-md-6">
                  <div class="form-floating">
                    <input type="text" class="form-control" id="lastname" placeholder="Last Name" required minlength="2">
                    <label for="lastname">Last Name</label>
                    <div class="invalid-feedback">
                      Last name must include at least two characters.
                    </div>
                  </div>
                </div>
              </div>
    
              <div class="row pb-3">
                <div class="col-md-12">
                  <button class="btn btn-warning" type="submit">Submit</button>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>