24. Advanced Forms & Validation
Why Advanced Forms Matter
Forms are the primary way users interact with web apps, from signing up and logging in to submitting data. Advanced forms go beyond simple inputs—they handle dynamic fields, complex validation, and provide immediate feedback, ensuring a smooth user experience.
Client-Side Validation Basics
HTML provides built-in validation attributes like `required`, `minlength`, `maxlength`, `pattern`, and `type`. Using them ensures basic correctness before the form is submitted.
<form id="signupForm">
<label>Email:</label>
<input type="email" name="email" required />
<label>Password:</label>
<input type="password" name="password" minlength="8" required />
<button type="submit">Sign Up</button>
</form>Built-in validation works, but real apps often need **custom validation logic** and **dynamic feedback**.
Custom Validation
You can attach JavaScript functions to validate fields dynamically, using `input` or `change` events. This allows for regex checks, cross-field validation, and conditional logic.
const form = document.getElementById('signupForm');
const emailInput = form.elements['email'];
const passwordInput = form.elements['password'];
form.addEventListener('submit', function(e) {
e.preventDefault();
const emailValid = /\S+@\S+\.\S+/.test(emailInput.value);
const passwordValid = passwordInput.value.length >= 8;
if (!emailValid) {
alert('Please enter a valid email');
} else if (!passwordValid) {
alert('Password must be at least 8 characters');
} else {
console.log('Form submitted!', { email: emailInput.value, password: passwordInput.value });
}
});Real-Time Feedback
Improve UX by giving instant feedback as users type. You can highlight invalid fields and show error messages dynamically.
emailInput.addEventListener('input', () => {
if (/\S+@\S+\.\S+/.test(emailInput.value)) {
emailInput.style.borderColor = 'green';
} else {
emailInput.style.borderColor = 'red';
}
});Dynamic & Conditional Fields
Some forms need fields to appear or change based on user input. For example, showing a 'State' field only if the country is USA.
const countrySelect = document.getElementById('country');
const stateInput = document.getElementById('state');
countrySelect.addEventListener('change', () => {
if (countrySelect.value === 'USA') {
stateInput.style.display = 'block';
stateInput.required = true;
} else {
stateInput.style.display = 'none';
stateInput.required = false;
}
});Form Submission & Async Validation
Advanced forms often need to check data against a server before submission (e.g., is a username taken?). This is done asynchronously with `fetch` or other AJAX techniques.
const usernameInput = form.elements['username'];
usernameInput.addEventListener('blur', async () => {
const res = await fetch(`/api/check-username?username=${usernameInput.value}`);
const data = await res.json();
if (!data.available) {
usernameInput.setCustomValidity('Username already taken');
} else {
usernameInput.setCustomValidity('');
}
});Mini Challenge
1. Create a registration form with fields: username, email, password, confirm password. 2. Validate that email is in correct format. 3. Password must be at least 8 characters and match confirm password. 4. Check username availability asynchronously using a mock API. 5. Provide real-time feedback and prevent submission until all validations pass.