Skip to content

Forms Validation

Form validation ensures that user input is correct, complete, and useful before it’s processed or submitted. Validation can occur on the client-side (in the browser using HTML and JavaScript) and on the server-side.

Client-Side Validation: The First Line of Defense

Section titled “Client-Side Validation: The First Line of Defense”

Client-side validation provides immediate feedback to the user, improving the user experience and reducing unnecessary server load. However, it should not be the only form of validation, as it can be bypassed. Always implement server-side validation as well.

HTML5 introduced several input attributes that allow browsers to perform basic validation automatically without any JavaScript:

  • required: Specifies that an input field must be filled out.
  • type: Defines the expected data type (e.g., email, number, url, date). Browsers will validate the format.
  • pattern: Specifies a regular expression that the input value must match.
  • min and max: Specify minimum and maximum values for numerical or date inputs.
  • minlength and maxlength: Specify minimum and maximum length for text-based inputs.

Example of HTML5 built-in validation:

<form id="myForm">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<label for="age">Age:</label>
<input type="number" id="age" name="age" min="18" max="99" required>
<label for="password">Password (min 8 chars, 1 number, 1 uppercase):</label>
<input type="password" id="password" name="password" required minlength="8"
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}">
<button type="submit">Submit</button>
</form>

Browsers will typically display default error messages for these built-in validations.

JavaScript Validation with the Constraint Validation API

Section titled “JavaScript Validation with the Constraint Validation API”

When HTML5 built-in validation is not sufficient, or you need more customized validation logic or error messages, you can use JavaScript. The Constraint Validation API provides properties and methods to work with the validity state of form elements.

Key DOM Properties and Methods for Validation:

Section titled “Key DOM Properties and Methods for Validation:”
  • element.validity: A ValidityState object with boolean properties indicating the validation status (e.g., validity.valueMissing, validity.typeMismatch, validity.patternMismatch, validity.valid).
  • element.validationMessage: A localized message describing the validation error if the element is invalid.
  • element.checkValidity(): Returns true if the element is valid, false otherwise. If invalid, it also fires an invalid event on the element.
  • form.checkValidity(): Returns true if all form elements are valid, false otherwise. Triggers invalid events on invalid elements.
  • element.setCustomValidity(message): Allows you to set a custom error message. If the message is an empty string, the element is considered valid regarding custom errors. If it’s a non-empty string, the element is invalid.

Example of JavaScript Validation:

function validateForm(event) {
const form = document.getElementById('userForm'); // Assuming form has id 'userForm'
const usernameInput = document.getElementById('username'); // Assuming input has id 'username'
const feedbackElement = document.getElementById('usernameFeedback'); // For displaying errors
// Custom validation logic for username
if (usernameInput.value.length < 5) {
usernameInput.setCustomValidity('Username must be at least 5 characters long.');
feedbackElement.textContent = usernameInput.validationMessage;
} else {
usernameInput.setCustomValidity(''); // Clear custom error
feedbackElement.textContent = '';
}
// Check overall form validity (including HTML5 and custom checks)
if (!form.checkValidity()) {
event.preventDefault(); // Prevent form submission if invalid
// Optionally, display a general error message or focus the first invalid field
console.log('Form is invalid. Please check the fields.');
// Iterate over invalid fields and display messages
Array.from(form.elements).forEach(el => {
if (!el.validity.valid && el.nextElementSibling && el.nextElementSibling.classList.contains('error-message')) {
el.nextElementSibling.textContent = el.validationMessage;
}
});
} else {
console.log('Form is valid and can be submitted.');
// Here you would typically allow the form to submit or send data via AJAX
// event.preventDefault(); // If submitting via AJAX
// submitFormData(new FormData(form));
}
}
const myForm = document.getElementById('userForm');
if (myForm) {
myForm.addEventListener('submit', validateForm);
// Optional: Add 'input' event listeners for real-time feedback
const usernameField = document.getElementById('username');
if(usernameField) {
usernameField.addEventListener('input', () => {
if (usernameField.validity.valid) {
usernameField.setCustomValidity('');
const feedback = document.getElementById('usernameFeedback');
if(feedback) feedback.textContent = '';
}
// Optionally, trigger validateForm or parts of it for immediate feedback
});
}
}
// HTML for the above example (simplified):
// <form id="userForm" novalidate> <!-- 'novalidate' disables browser's default bubbles -->
// <label for="username">Username:</label>
// <input type="text" id="username" name="username" required>
// <span class="error-message" id="usernameFeedback"></span>
// <button type="submit">Register</button>
// </form>

Setting the novalidate attribute on the <form> element disables the browser’s default validation UI (like error bubbles), allowing you to implement a fully custom feedback mechanism.

The primary purpose of data validation is to ensure the data is:

  • Complete: All required fields are filled.
  • Correct: Data is in the right format (e.g., valid email, numeric for age).
  • Consistent: Data adheres to business rules (e.g., password complexity).
  • Secure: Protects against common vulnerabilities like Cross-Site Scripting (XSS) by sanitizing input (primarily a server-side concern, but client-side can help guide users).

Constraint Validation CSS Pseudo-Selectors

Section titled “Constraint Validation CSS Pseudo-Selectors”

CSS provides pseudo-classes that allow you to style form elements based on their validation state:

SelectorDescription
:validSelects input elements with valid values.
:invalidSelects input elements with invalid values.
:requiredSelects input elements with the required attribute.
:optionalSelects input elements without the required attribute.
:in-rangeSelects input elements whose value is within the min and max range.
:out-of-rangeSelects input elements whose value is outside the min and max range.

Example CSS for styling invalid fields:

input:invalid {
border-color: red;
background-color: #fff0f0;
}
input:valid {
border-color: green;
}

For a full list, refer to CSS Pseudo-classes on MDN.