Skillversitas

Advanced Form Validation

Form validation ensures that the data submitted by users matches the expected format.

HTML5 Built-in Validation

Required Attribute

<input type="text" name="name" required>

Input Types

<input type="email" name="email">
<input type="url" name="website">
<input type="tel" name="phone">
<input type="number" name="age" min="17" max="60">
<input type="date" name="date_of_birth">

Pattern Regex

<input type="text" name="studentId" pattern="[0-9]{10}" title="StudentID must be 10 digits">
<input type="text" name="phone" pattern="08[0-9]{10}" title="Format: 08xxxxxxxxxx">

JavaScript Validation

Email

<script>
    function validateEmail(email) {
        const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return re.test(email);
    }
</script>

Password Strength

<script>
    function checkPassword(password) {
        let strength = 0;
        if (password.length >= 8) strength++;
        if (password.match(/[a-z]/) && password.match(/[A-Z]/)) strength++;
        if (password.match(/[0-9]/)) strength++;
        if (password.match(/[^a-zA-Z0-9]/)) strength++;
        return strength;
    }
</script>

Case Study: Student Registration Form

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Student Registration Form</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: 'Segoe UI', sans-serif; background: #f0f2f5; padding: 2rem; }
        .container { max-width: 600px; margin: 0 auto; }
        .card { background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h1 { color: #1e3a5f; margin-bottom: 1.5rem; text-align: center; }
        .form-group { margin-bottom: 1.5rem; }
        label { display: block; margin-bottom: 0.5rem; font-weight: 500; }
        input, select { width: 100%; padding: 0.8rem; border: 2px solid #ddd; border-radius: 4px; font-size: 1rem; }
        input:focus, select:focus { outline: none; border-color: #3498db; }
        input.valid { border-color: #2ecc71; }
        input.invalid { border-color: #e74c3c; }
        .error { color: #e74c3c; font-size: 0.85rem; margin-top: 0.3rem; display: none; }
        .error.active { display: block; }
        .hint { color: #666; font-size: 0.85rem; margin-top: 0.3rem; }
        .strength-bar { height: 5px; background: #e9ecef; border-radius: 3px; margin-top: 0.5rem; }
        .strength-fill { height: 100%; width: 0%; transition: all 0.3s; }
        .btn { width: 100%; padding: 0.8rem; background: #3498db; color: white; border: none; border-radius: 4px; font-size: 1rem; cursor: pointer; margin-top: 1rem; }
        .btn:hover { background: #2980b9; }
        .btn:disabled { background: #bdc3c7; cursor: not-allowed; }
        .success { background: #d4edda; color: #155724; padding: 1rem; border-radius: 4px; margin-top: 1rem; display: none; }
    </style>
</head>
<body>
    <div class="container">
        <div class="card">
            <h1>New Student Registration</h1>

            <form id="registrationForm" novalidate>
                <div class="form-group">
                    <label for="name">Full name <span style="color: red;">*</span></label>
                    <input type="text" id="name" name="name" placeholder="Enter your full name">
                    <div class="error" id="nameError">Name at least 3 characters</div>
                </div>

                <div class="form-group">
                    <label for="studentId">StudentID <span style="color: red;">*</span></label>
                    <input type="text" id="studentId" name="studentId" placeholder="10 digits">
                    <div class="error" id="studentIdError">StudentID must be 10 digits</div>
                    <div class="hint">Example: 1234567890</div>
                </div>

                <div class="form-group">
                    <label for="email">Email <span style="color: red;">*</span></label>
                    <input type="email" id="email" name="email" placeholder="[email protected]">
                    <div class="error" id="emailError">Invalid email</div>
                </div>

                <div class="form-group">
                    <label for="password">Password <span style="color: red;">*</span></label>
                    <input type="password" id="password" name="password" placeholder="At least 8 characters">
                    <div class="strength-bar"><div class="strength-fill" id="strengthFill"></div></div>
                    <div class="hint" id="passwordHint">Use a combination of uppercase, lowercase, digits, and symbols</div>
                </div>

                <div class="form-group">
                    <label for="confirmPassword">Confirm Password <span style="color: red;">*</span></label>
                    <input type="password" id="confirmPassword" placeholder="Confirm password">
                    <div class="error" id="confirmError">Passwords do not match</div>
                </div>

                <div class="form-group">
                    <label for="phone">Phone Number</label>
                    <input type="tel" id="phone" name="phone" placeholder="08xxxxxxxxxx">
                    <div class="error" id="teleponError">Format: 08 diikuti 10 digits</div>
                </div>

                <div class="form-group">
                    <label for="major">Major <span style="color: red;">*</span></label>
                    <select id="major" name="major">
                        <option value="">Select Major</option>
                        <option value="cs">Computer Science</option>
                        <option value="si">Information Systems</option>
                        <option value="management">Management/option>
                        <option value="accounting">Accounting/option>
                    </select>
                    <div class="error" id="majorError">Select your major</div>
                </div>

                <button type="submit" class="btn" id="submitBtn" disabled>Sign Up Now</button>
            </form>

            <div class="success" id="successMsg">
                Registration successful! Please check your email to confirm.
            </div>
        </div>
    </div>

    <script>
        const form = document.getElementById('registrationForm');
        const submitBtn = document.getElementById('submitBtn');

        const validators = {
            name: (v) => v.length >= 3,
            studentId: (v) => /^[0-9]{10}$/.test(v),
            email: (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
            password: (v) => v.length >= 8,
            confirmPassword: (v) => v === document.getElementById('password').value && v.length > 0,
            major: (v) => v !== ''
        };

        function validateField(id, validator) {
            const input = document.getElementById(id);
            const error = document.getElementById(id + 'Error');
            const isValid = validator(input.value.trim());

            if (isValid) {
                input.classList.remove('invalid');
                input.classList.add('valid');
                if (error) error.classList.remove('active');
            } else if (input.value.length > 0) {
                input.classList.remove('valid');
                input.classList.add('invalid');
                if (error) error.classList.add('active');
            } else {
                input.classList.remove('valid', 'invalid');
                if (error) error.classList.remove('active');
            }

            return isValid;
        }

        function checkAllValid() {
            const nameValid = validateField('name', validators.name);
            const studentIdValid = validateField('studentId', validators.studentId);
            const emailValid = validateField('email', validators.email);
            const passValid = validateField('password', validators.password);
            const confirmValid = validateField('confirmPassword', validators.confirmPassword);
            const majorValid = validateField('major', validators.major);

            submitBtn.disabled = !(nameValid && studentIdValid && emailValid && passValid && confirmValid && majorValid);
        }

        ['name', 'studentId', 'email', 'password', 'confirmPassword', 'major'].forEach(id => {
            document.getElementById(id).addEventListener('input', checkAllValid);
            document.getElementById(id).addEventListener('change', checkAllValid);
        });

        document.getElementById('phone').addEventListener('input', function() {
            validateField('phone', (v) => v === '' || /^08[0-9]{10}$/.test(v));
        });

        document.getElementById('password').addEventListener('input', function() {
            const password = this.value;
            let strength = 0;
            if (password.length >= 8) strength += 25;
            if (password.match(/[a-z]/) && password.match(/[A-Z]/)) strength += 25;
            if (password.match(/[0-9]/)) strength += 25;
            if (password.match(/[^a-zA-Z0-9]/)) strength += 25;

            const fill = document.getElementById('strengthFill');
            fill.style.width = strength + '%';
            fill.style.background = strength <= 25 ? '#e74c3c' : strength <= 50 ? '#f39c12' : strength <= 75 ? '#3498db' : '#2ecc71';

            checkAllValid();
        });

        form.addEventListener('submit', function(e) {
            e.preventDefault();
            document.getElementById('successMsg').style.display = 'block';
            submitBtn.disabled = true;
        });
    </script>
</body>
</html>

Best Practices

  1. Server-side validation: Always validate on the server too
  2. Clear error messages: Explain what's wrong
  3. Real-time validation: Provide feedback while typing
  4. Don't rely on required alone: Add JavaScript validation
  5. Accessibility: Link error messages with the input

Summary

Form validation is important for data integrity and user experience. Combine HTML5 and JavaScript validation for the best results.