Form validation is the first line of defense to ensure the data users submit matches what the application expects. Even though modern browsers already have built-in HTML5 validation such as the required attribute and type="email", validation with JavaScript gives us full control over the logic, the display of error messages, and a better user experience.
Why Is JavaScript Validation Needed?
- Error messages can be customized to the app's language and design style.
- It can validate complex conditions that HTML5 alone can't handle.
- Validation can be done in real time as the user types.
- Consistent appearance across all browsers.
Keep in mind: JavaScript validation is client-side only. Always also validate on the server side for security.
HTML Form Structure
<!-- The basic form structure we'll validate -->
<form id="registration-form">
<div class="form-group">
<label for="name">Full Name</label>
<input type="text" id="name" name="name" placeholder="Enter your full name">
<span class="error-message" id="error-name"></span>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" id="email" name="email" placeholder="example@email.com">
<span class="error-message" id="error-email"></span>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password">
<span class="error-message" id="error-password"></span>
</div>
<button type="submit">Sign Up Now</button>
</form>
Basic Validation Functions
We create small, specific functions for each type of validation:
// Helper function: show an error message
function showError(errorId, message) {
const el = document.getElementById(errorId);
el.textContent = message;
el.style.color = 'red';
el.style.fontSize = '0.85em';
}
// Helper function: clear an error message
function clearError(errorId) {
document.getElementById(errorId).textContent = '';
}
// Validate name — at least 3 characters, no numbers
function validateName(value) {
if (!value.trim()) {
return 'Name cannot be empty.';
}
if (value.trim().length < 3) {
return 'Name must be at least 3 characters.';
}
if (/\d/.test(value)) {
return 'Name cannot contain numbers.';
}
return ''; // empty means valid
}
// Validate email with a regex
function validateEmail(value) {
if (!value.trim()) {
return 'Email cannot be empty.';
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(value)) {
return 'Invalid email format. Example: name@domain.com';
}
return '';
}
// Validate password — at least 8 characters, must contain a letter & a number
function validatePassword(value) {
if (!value) {
return 'Password cannot be empty.';
}
if (value.length < 8) {
return 'Password must be at least 8 characters.';
}
if (!/[A-Za-z]/.test(value)) {
return 'Password must contain at least one letter.';
}
if (!/[0-9]/.test(value)) {
return 'Password must contain at least one number.';
}
return '';
}
Real-Time Validation (While Typing)
Giving instant feedback while the user types makes the experience much better:
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
// Validate when the user leaves the field (blur)
nameInput.addEventListener('blur', function() {
const message = validateName(this.value);
if (message) {
showError('error-name', message);
this.style.borderColor = 'red';
} else {
clearError('error-name');
this.style.borderColor = 'green';
}
});
emailInput.addEventListener('blur', function() {
const message = validateEmail(this.value);
if (message) {
showError('error-email', message);
this.style.borderColor = 'red';
} else {
clearError('error-email');
this.style.borderColor = 'green';
}
});
// Validate while typing for the password (real-time)
passwordInput.addEventListener('input', function() {
const message = validatePassword(this.value);
if (message) {
showError('error-password', message);
} else {
clearError('error-password');
}
});
Validation on Submit
Besides real-time validation, make sure all fields are validated when the form is submitted:
const form = document.getElementById('registration-form');
form.addEventListener('submit', function(e) {
e.preventDefault(); // Prevent the default form submission
const nameValue = nameInput.value;
const emailValue = emailInput.value;
const passwordValue = passwordInput.value;
const nameError = validateName(nameValue);
const emailError = validateEmail(emailValue);
const passwordError = validatePassword(passwordValue);
// Show all errors
if (nameError) showError('error-name', nameError);
else clearError('error-name');
if (emailError) showError('error-email', emailError);
else clearError('error-email');
if (passwordError) showError('error-password', passwordError);
else clearError('error-password');
// If everything is valid (no error messages)
const allValid = !nameError && !emailError && !passwordError;
if (allValid) {
console.log('Form is valid! Ready to send to the server.');
console.log({
name: nameValue,
email: emailValue,
password: passwordValue
});
// Here you can use fetch/axios to send the data to the server
alert('Registration successful!');
form.reset();
} else {
// Focus on the first field with an error
const fieldError = [
{ el: nameInput, err: nameError },
{ el: emailInput, err: emailError },
{ el: passwordInput, err: passwordError }
].find(item => item.err);
if (fieldError) fieldError.el.focus();
}
});
Conclusion
Form validation with JavaScript lets us provide a far better user experience than relying on HTML5 validation alone. By separating validation functions per field, showing errors in real time, and performing a complete check on submit, your form will be more user-friendly and its data more reliable. Always remember to add similar validation on the server side as an extra security layer.