Bootstrap 5 Tutorial

v5.3.0

Bootstrap 5 Tutorial

Form Validation in Bootstrap 5

Form Validation: Bootstrap 5 provides built-in validation styles and JavaScript for client-side form validation.

Browser Default Validation

HTML5 Built-in Validation
HTML5 email validation with required attribute
HTML5 number validation with min/max
HTML5 pattern validation with regex
<!-- HTML5 Validation Examples -->
            <form>
            <!-- Required Email -->
            <div class="mb-3">
                <label for="html5Email" class="form-label">Email</label>
                <input 
                type="email" 
                class="form-control" 
                id="html5Email" 
                required
                placeholder="name@example.com"
                >
            </div>
            
            <!-- Number with Min/Max -->
            <div class="mb-3">
                <label for="html5Number" class="form-label">Age</label>
                <input 
                type="number" 
                class="form-control" 
                id="html5Number" 
                min="18"
                max="100"
                required
                >
            </div>
            
            <!-- Pattern Validation -->
            <div class="mb-3">
                <label for="html5Pattern" class="form-label">ZIP Code</label>
                <input 
                type="text" 
                class="form-control" 
                id="html5Pattern" 
                pattern="^\d{5}(-\d{4})?$"
                required
                title="Enter valid ZIP code"
                >
            </div>
            </form>

Bootstrap Validation Styles

Custom Validation Classes
Looks good!
Please provide a valid value.
Good choice!
Please select a valid option.
You must check this box.
You must agree before submitting.
<!-- Valid Input -->
            <div class="mb-3">
            <label for="validInput" class="form-label">Valid input</label>
            <input 
                type="text" 
                class="form-control is-valid" 
                id="validInput" 
                value="Correct value"
            >
            <div class="valid-feedback">
                Looks good!
            </div>
            </div>

            <!-- Invalid Input -->
            <div class="mb-3">
            <label for="invalidInput" class="form-label">Invalid input</label>
            <input 
                type="text" 
                class="form-control is-invalid" 
                id="invalidInput" 
                value="Wrong value"
            >
            <div class="invalid-feedback">
                Please provide a valid value.
            </div>
            </div>

            <!-- Valid Select -->
            <div class="mb-3">
            <label for="validSelect" class="form-label">Valid select</label>
            <select class="form-select is-valid" id="validSelect">
                <option selected>Open this select menu</option>
            </select>
            <div class="valid-feedback">
                Good choice!
            </div>
            </div>

            <!-- Invalid Checkbox -->
            <div class="form-check">
            <input class="form-check-input is-invalid" type="checkbox" id="invalidCheck">
            <label class="form-check-label" for="invalidCheck">
                Invalid checkbox
            </label>
            <div class="invalid-feedback">
                You must agree before submitting.
            </div>
            </div>

Complete Validation Example

Registration Form with Validation
@
Must be at least 3 characters
We'll never share your email with anyone else.
Minimum 6 characters
<!-- Complete Validation Example -->
            <form onSubmit={handleSubmit} noValidate>
            <!-- First Name with Validation -->
            <div class="mb-3">
                <label for="firstName" class="form-label">First Name *</label>
                <input 
                type="text" 
                class={`form-control ${errors.firstName ? 'is-invalid' : ''}`}
                id="firstName"
                name="firstName"
                value={formData.firstName}
                onChange={handleChange}
                required
                >
                {errors.firstName && (
                <div class="invalid-feedback">{errors.firstName}</div>
                )}
            </div>
            
            <!-- Email with Validation -->
            <div class="mb-3">
                <label for="email" class="form-label">Email *</label>
                <input 
                type="email" 
                class={`form-control ${errors.email ? 'is-invalid' : ''}`}
                id="email"
                name="email"
                value={formData.email}
                onChange={handleChange}
                required
                >
                {errors.email && (
                <div class="invalid-feedback">{errors.email}</div>
                )}
            </div>
            
            <!-- Checkbox with Validation -->
            <div class={`form-check ${errors.agreeTerms ? 'is-invalid' : ''}`}>
                <input 
                type="checkbox" 
                class={`form-check-input ${errors.agreeTerms ? 'is-invalid' : ''}`}
                id="agreeTerms"
                name="agreeTerms"
                checked={formData.agreeTerms}
                onChange={handleChange}
                required
                >
                <label class="form-check-label" for="agreeTerms">
                I agree to terms *
                </label>
                {errors.agreeTerms && (
                <div class="invalid-feedback">{errors.agreeTerms}</div>
                )}
            </div>
            </form>

Server-side Validation Example

Simulated Server Validation
Taken usernames: admin, user, test, demo
<!-- Server-side Validation Simulation -->
            <form onSubmit={handleSubmit}>
            <div class="mb-3">
                <label for="serverUsername" class="form-label">Check Username</label>
                <input 
                type="text" 
                class="form-control" 
                id="serverUsername"
                placeholder="Enter username"
                required
                >
                <div class="invalid-feedback"></div>
            </div>
            
            <button type="submit" class="btn btn-primary">Check Availability</button>
            </form>

            <script>
            // Simulated server validation
            const takenUsernames = ['admin', 'user', 'test', 'demo'];
            
            function handleSubmit(e) {
                e.preventDefault();
                const username = e.target.username.value;
                
                if (takenUsernames.includes(username.toLowerCase())) {
                e.target.username.classList.add('is-invalid');
                e.target.nextElementSibling.textContent = 'Username is already taken';
                } else {
                e.target.username.classList.remove('is-invalid');
                e.target.username.classList.add('is-valid');
                alert('Username available!');
                }
            }
            </script>

Validation with Tooltips

Tooltip Validation Feedback
Please provide a valid first name.
Please provide a valid last name.
@
Please provide a valid email.
<!-- Validation with Tooltips -->
            <form class="needs-validation" novalidate>
            <div class="position-relative">
                <label for="tooltipFirstName" class="form-label">First name</label>
                <input 
                type="text" 
                class="form-control" 
                id="tooltipFirstName" 
                required
                >
                <div class="invalid-tooltip">
                Please provide a valid first name.
                </div>
            </div>
            
            <div class="position-relative">
                <label for="tooltipEmail" class="form-label">Email</label>
                <div class="input-group has-validation">
                <span class="input-group-text">@</span>
                <input 
                    type="email" 
                    class="form-control" 
                    id="tooltipEmail" 
                    required
                >
                <div class="invalid-tooltip">
                    Please provide a valid email.
                </div>
                </div>
            </div>
            </form>

Custom Validation Messages

Customizing Validation Feedback
✅ Perfect! This looks great.
❌ Oops! There's an issue with this field.
Please check your input and try again.
📧
⚠️Please enter a valid email address
<!-- Custom Valid Feedback -->
            <div class="mb-3">
            <input type="text" class="form-control is-valid">
            <div class="valid-feedback" style="color: #198754; font-weight: bold;">
                ✅ Perfect! This looks great.
            </div>
            </div>

            <!-- Custom Invalid Feedback -->
            <div class="mb-3">
            <input type="text" class="form-control is-invalid">
            <div class="invalid-feedback" style="color: #dc3545; font-size: 0.9rem;">
                ❌ Oops! There's an issue.
                <br>
                <small>Please check your input.</small>
            </div>
            </div>

            <!-- Validation with Icons -->
            <div class="input-group has-validation">
            <span class="input-group-text">📧</span>
            <input type="email" class="form-control is-invalid">
            <span class="input-group-text">
                <span class="text-danger">❌</span>
            </span>
            <div class="invalid-feedback d-flex align-items-center">
                <span class="me-2">⚠️</span>
                <span>Please enter a valid email</span>
            </div>
            </div>

Real-time Validation

Live Validation Feedback
<!-- Real-time Password Validation -->
            <input 
            type="password" 
            class="form-control" 
            id="livePassword"
            oninput="validatePassword(this)"
            >
            <div id="passwordFeedback"></div>

            <script>
            function validatePassword(input) {
            const value = input.value;
            const feedback = document.getElementById('passwordFeedback');
            
            if (value.length === 0) {
                input.classList.remove('is-valid', 'is-invalid');
                feedback.textContent = '';
            } else if (value.length < 6) {
                input.classList.remove('is-valid');
                input.classList.add('is-invalid');
                feedback.textContent = 'Password too short';
                feedback.className = 'invalid-feedback';
            } else if (!/[A-Z]/.test(value)) {
                input.classList.remove('is-valid');
                input.classList.add('is-invalid');
                feedback.textContent = 'Add uppercase letter';
                feedback.className = 'invalid-feedback';
            } else {
                input.classList.remove('is-invalid');
                input.classList.add('is-valid');
                feedback.textContent = 'Strong password!';
                feedback.className = 'valid-feedback';
            }
            }
            </script>

Validation Best Practices

Client-side Validation Guidelines
  • Always validate on server: Client-side validation is for UX, not security
  • Provide immediate feedback: Validate on blur or as user types
  • Use clear messages: Explain what's wrong and how to fix it
  • Be specific: Don't just say "invalid" - say why it's invalid
  • Use appropriate validation: HTML5 attributes first, then custom JavaScript
  • Consider accessibility: Ensure validation messages are accessible to screen readers
  • Test thoroughly: Test all validation scenarios and edge cases
Common Validation Mistakes
  • ❌ Relying solely on client-side validation for security
  • ❌ Not clearing validation states when user corrects errors
  • ❌ Using vague or technical error messages
  • ❌ Validating too early (on every keystroke)
  • ❌ Not validating on form submission
  • ❌ Forgetting to validate required fields
  • ❌ Not testing with different input types and browsers