Bootstrap 5 Framework

Form Validation

13 min Lesson 19 of 40

Introduction to Form Validation

Form validation is crucial for ensuring data quality and providing user feedback. Bootstrap 5 provides extensive validation styles that work with both browser default validation and custom validation logic. Proper validation improves user experience and data integrity.

Note: Bootstrap validation styles require JavaScript to toggle validation classes based on form state. You can use the browser's built-in validation API or custom validation logic.

Browser Default Validation

HTML5 provides built-in form validation attributes. Bootstrap styles these automatically:

<form class="row g-3"> <div class="col-md-4"> <label for="validationDefault01" class="form-label">First name</label> <input type="text" class="form-control" id="validationDefault01" value="Mark" required> </div> <div class="col-md-4"> <label for="validationDefault02" class="form-label">Last name</label> <input type="text" class="form-control" id="validationDefault02" value="Otto" required> </div> <div class="col-md-4"> <label for="validationDefaultUsername" class="form-label">Username</label> <div class="input-group"> <span class="input-group-text">@</span> <input type="text" class="form-control" id="validationDefaultUsername" required> </div> </div> <div class="col-md-6"> <label for="validationDefault03" class="form-label">City</label> <input type="text" class="form-control" id="validationDefault03" required> </div> <div class="col-md-3"> <label for="validationDefault04" class="form-label">State</label> <select class="form-select" id="validationDefault04" required> <option selected disabled value="">Choose...</option> <option>...</option> </select> </div> <div class="col-md-3"> <label for="validationDefault05" class="form-label">Zip</label> <input type="text" class="form-control" id="validationDefault05" required> </div> <div class="col-12"> <button class="btn btn-primary" type="submit">Submit form</button> </div> </form>
Tip: Use HTML5 validation attributes like required, min, max, pattern, minlength, and maxlength for basic validation.

Custom Validation Styles

For custom Bootstrap validation styles, use was-validated class on the form or is-valid/is-invalid classes on individual controls:

<form class="row g-3 needs-validation" novalidate> <div class="col-md-4"> <label for="validationCustom01" class="form-label">First name</label> <input type="text" class="form-control" id="validationCustom01" value="Mark" required> <div class="valid-feedback"> Looks good! </div> </div> <div class="col-md-4"> <label for="validationCustom02" class="form-label">Last name</label> <input type="text" class="form-control" id="validationCustom02" value="Otto" required> <div class="valid-feedback"> Looks good! </div> </div> <div class="col-md-4"> <label for="validationCustomUsername" class="form-label">Username</label> <div class="input-group has-validation"> <span class="input-group-text">@</span> <input type="text" class="form-control" id="validationCustomUsername" required> <div class="invalid-feedback"> Please choose a username. </div> </div> </div> <div class="col-md-6"> <label for="validationCustom03" class="form-label">City</label> <input type="text" class="form-control" id="validationCustom03" required> <div class="invalid-feedback"> Please provide a valid city. </div> </div> <div class="col-md-3"> <label for="validationCustom04" class="form-label">State</label> <select class="form-select" id="validationCustom04" required> <option selected disabled value="">Choose...</option> <option>...</option> </select> <div class="invalid-feedback"> Please select a valid state. </div> </div> <div class="col-md-3"> <label for="validationCustom05" class="form-label">Zip</label> <input type="text" class="form-control" id="validationCustom05" required> <div class="invalid-feedback"> Please provide a valid zip. </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"> Agree to terms and conditions </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 form</button> </div> </form> <script> // Example JavaScript for custom validation (function () { 'use strict' // Fetch all forms that need validation 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) }) })() </script>
Note: Use novalidate attribute to disable browser default validation tooltips when using custom validation.

Validation Feedback Messages

Bootstrap provides two types of feedback messages: valid and invalid:

<!-- Valid feedback --> <div class="mb-3"> <label for="validInput" class="form-label">Valid input</label> <input type="text" class="form-control is-valid" id="validInput" value="Valid value"> <div class="valid-feedback"> Great! This looks good. </div> </div> <!-- Invalid feedback --> <div class="mb-3"> <label for="invalidInput" class="form-label">Invalid input</label> <input type="text" class="form-control is-invalid" id="invalidInput"> <div class="invalid-feedback"> Please provide a valid value. </div> </div> <!-- Valid tooltip --> <div class="mb-3 position-relative"> <label for="validTooltip" class="form-label">Valid tooltip</label> <input type="text" class="form-control is-valid" id="validTooltip" value="Valid value"> <div class="valid-tooltip"> Looks good! </div> </div> <!-- Invalid tooltip --> <div class="mb-3 position-relative"> <label for="invalidTooltip" class="form-label">Invalid tooltip</label> <input type="text" class="form-control is-invalid" id="invalidTooltip"> <div class="invalid-tooltip"> Please provide a valid value. </div> </div>
Tip: Use valid-tooltip and invalid-tooltip instead of valid-feedback and invalid-feedback for tooltip-style validation messages.

Server-Side Validation Styling

Apply validation states directly to form controls using is-valid and is-invalid classes for server-side validation:

<form> <!-- Valid server-side validation --> <div class="mb-3"> <label for="serverValidEmail" class="form-label">Email</label> <input type="email" class="form-control is-valid" id="serverValidEmail" value="user@example.com"> <div class="valid-feedback"> Email is available. </div> </div> <!-- Invalid server-side validation --> <div class="mb-3"> <label for="serverInvalidUsername" class="form-label">Username</label> <input type="text" class="form-control is-invalid" id="serverInvalidUsername" value="admin"> <div class="invalid-feedback"> This username is already taken. Please choose another. </div> </div> <!-- Multiple validation errors --> <div class="mb-3"> <label for="serverInvalidPassword" class="form-label">Password</label> <input type="password" class="form-control is-invalid" id="serverInvalidPassword"> <div class="invalid-feedback"> <ul class="mb-0"> <li>Password must be at least 8 characters</li> <li>Password must contain at least one uppercase letter</li> <li>Password must contain at least one number</li> </ul> </div> </div> <button type="submit" class="btn btn-primary">Submit</button> </form>

Disabled and Readonly States

Disabled and readonly inputs don't trigger validation:

<form class="was-validated"> <!-- Disabled input (no validation) --> <div class="mb-3"> <label for="disabledInput" class="form-label">Disabled input</label> <input type="text" class="form-control" id="disabledInput" disabled required> </div> <!-- Readonly input (no validation) --> <div class="mb-3"> <label for="readonlyInput" class="form-label">Readonly input</label> <input type="text" class="form-control" id="readonlyInput" value="Readonly value" readonly required> </div> <!-- Regular input (validated) --> <div class="mb-3"> <label for="regularInput" class="form-label">Regular input</label> <input type="text" class="form-control" id="regularInput" required> <div class="invalid-feedback"> This field is required. </div> </div> <button type="submit" class="btn btn-primary">Submit</button> </form>

Validation with Different Input Types

Apply validation to various input types:

<form class="row g-3 needs-validation" novalidate> <!-- Email validation --> <div class="col-md-6"> <label for="validationEmail" class="form-label">Email</label> <input type="email" class="form-control" id="validationEmail" required> <div class="invalid-feedback"> Please provide a valid email address. </div> </div> <!-- URL validation --> <div class="col-md-6"> <label for="validationUrl" class="form-label">Website</label> <input type="url" class="form-control" id="validationUrl" required> <div class="invalid-feedback"> Please provide a valid URL. </div> </div> <!-- Number validation with min/max --> <div class="col-md-6"> <label for="validationNumber" class="form-label">Age (18-120)</label> <input type="number" class="form-control" id="validationNumber" min="18" max="120" required> <div class="invalid-feedback"> Age must be between 18 and 120. </div> </div> <!-- Date validation --> <div class="col-md-6"> <label for="validationDate" class="form-label">Date of Birth</label> <input type="date" class="form-control" id="validationDate" required> <div class="invalid-feedback"> Please select a valid date. </div> </div> <!-- Pattern validation --> <div class="col-md-6"> <label for="validationPhone" class="form-label">Phone Number</label> <input type="tel" class="form-control" id="validationPhone" pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" placeholder="123-456-7890" required> <div class="invalid-feedback"> Phone number must be in format: 123-456-7890 </div> </div> <!-- Length validation --> <div class="col-md-6"> <label for="validationPassword" class="form-label">Password</label> <input type="password" class="form-control" id="validationPassword" minlength="8" maxlength="20" required> <div class="invalid-feedback"> Password must be 8-20 characters long. </div> </div> <!-- Textarea validation --> <div class="col-12"> <label for="validationTextarea" class="form-label">Comments</label> <textarea class="form-control" id="validationTextarea" rows="3" maxlength="500" required></textarea> <div class="invalid-feedback"> Please provide comments (max 500 characters). </div> </div> <!-- Select validation --> <div class="col-12"> <label for="validationCountry" class="form-label">Country</label> <select class="form-select" id="validationCountry" required> <option value="">Choose...</option> <option value="us">United States</option> <option value="uk">United Kingdom</option> <option value="ca">Canada</option> </select> <div class="invalid-feedback"> Please select a country. </div> </div> <!-- File validation --> <div class="col-12"> <label for="validationFile" class="form-label">Upload Resume (PDF only)</label> <input type="file" class="form-control" id="validationFile" accept=".pdf" required> <div class="invalid-feedback"> Please upload a PDF file. </div> </div> <div class="col-12"> <button class="btn btn-primary" type="submit">Submit form</button> </div> </form>
Warning: Client-side validation is for user experience only. Always validate data on the server-side to ensure security and data integrity.

Exercise: Create a Validated Contact Form

Create a complete contact form with custom validation including:

  1. Full Name field (required, 3-50 characters)
  2. Email field (required, valid email format)
  3. Phone field (required, pattern: XXX-XXX-XXXX)
  4. Subject dropdown (required, at least 3 options)
  5. Message textarea (required, 10-500 characters)
  6. Preferred contact method checkboxes (at least one required)
  7. Privacy policy checkbox (required)
  8. Custom validation feedback messages for each field
  9. Use was-validated class on form submission
  10. Include both valid and invalid feedback styling
  11. Add submit button that triggers validation

Best Practices

  • Always provide clear, specific error messages that tell users how to fix the problem
  • Validate on both client-side and server-side for security
  • Show validation feedback in real-time when possible
  • Use appropriate HTML5 input types for better mobile keyboards
  • Don't rely solely on placeholder text for instructions
  • Group related validation errors together
  • Use positive validation feedback to encourage users
  • Make validation messages accessible with ARIA attributes
  • Consider inline validation for better user experience
  • Test validation with keyboard navigation and screen readers
  • Disable submit button during form processing to prevent double submission

Summary

In this lesson, you learned about form validation in Bootstrap 5, including browser default validation, custom validation styles, validation feedback messages, server-side validation styling, and validation for different input types. Proper form validation is essential for data quality, user experience, and application security.