Validating HTML Forms using JavaScript and Constraint Validation API
The primary reason code breaks is due to unexpected input. If we have a function that expects a string as its argument but gets called with an integer, the function will behave unexpectedly, hence the need to protect the items that is send to out functions and classes.
Introduction
HTML forms is the primary way of receiving user data in our web applications. Almost all websites you visit has some kind of form in it. starting from Google, Facebook, etc.
Forms are used all around us, hence the need to protect the content received through them.
HTML has a number of form elements which is used in receiving different kind of input. The text input <input type="text">
is used to receive text inputs from the user.
<input type="number">
is used to receive numeric inputs from the user. You can learn more about form elements here.
Why protect forms?
Protecting the data received through forms mean making sure that correct data is given by the user and if the user provides incorrect data, we prevent the form from being submitted.
Adding validation
In every form, some information are important and necessary while some are optional. The first and simplest phase of form validation is specifying which information is important and required.
You can do so by adding the required attribute to the form element.
/ Optional
<input type="text" name="name" id="name">
// Important and required
<input type="text" name="name" id="name" required>
By adding the required attribute, the browser knows that this particular element must be filled and will not allow the form to be submitted if the user tries to submit it.The browser even helps us by adding a tooltip stating that the input field must be filled.
The next phase of validation is making sure that the information filled by the user is actually correct.If we have an input field that expects an email address to be filled, using an input with type=”text”
will not suffice. Thankfully, HTML 5 has an input type of email. Hence, if we are expecting the user to fill his email, we need to use <input type="email">
.
Using Javascript for validation
Complications set in when we want to check for more complex stuff. For example, if we want the user to enter a text that has a specific number of characters, there is no HTML 5 form element to handle that. Instead, we can handle it using javascript.
// html
<input type="text" name="name" id="name">
// script
const nameField = document.querySelector('#name');
nameField.addEventListener('input', function(event) {
const value = event.target.value;
if(value.length === 10 || value.length === 0) {
nameField.style.borderColor = 'black';
} else {
nameField.style.borderColor = 'red';
}
})
In the snippet above, we listen for the input event, and check the length of the currently entered data. if the data is not 10, then we change the border of the element to red, denoting a warning to the user. When the user types exactly 10 characters, we set the border color to black. We also set the border color to black when there is no item in the input field — value.length === 0
.
This technique can be used to add some interesting validation to HTML forms.
HTML 5 comes with some interesting validation methods which can be applied to forms. As already discussed above, not all possible validations are provided in HTML 5, but quite a number of good ones are there and the best way to use it is by combining HTML 5 validation with your own custom validation.
Still using the name example, our custom validation checked that the number of characters is 10, we will update it to also check that the input is actually field. HTML 5 provides a simple way of doing this — the required attribute.Adding the required attribute to the input field, we get
// html
<input type="text" name="name" id="name" required>
// javascript
const nameField = document.querySelector('#name');
nameField.addEventListener('input', function(event) {
const value = event.target.value;
const isValid = (nameField.validity.valid && value.length === 10);
if(isValid) {
nameField.style.borderColor = 'black';
} else {
nameField.style.borderColor = 'red';
}
})
The snippet above looks similar to the previous example, but with a few changes.The most visible change here is the use of nameField.validity.valid. This is a part of the HTML 5 Constraint Validation API.
Using the Constraint Validation API for validation
This API exposes some properties like: valid, valueMissing, typeMismatch, patternMismatch, tooLong, tooShort, rangeUnderflow, rangeOverflow, stepMismatch, badInput, customError.
nameField.validity.valid
as used above checks if the element is valid following the HTML 5 validation rule set by us — required.
We set this rule by adding the required attribute to the input field. Other validation properties are active in other input types.
For example, rangeUnderflow, rangeOverflow, stepMismatch can be used when validating input fields. To use this, the min, max and step attributes must be set in the form element.
<input type="number" name="num" id="num" min="10" max="20" required>
<span style="display: none;" id="messagebox"></span>
The span element is added below to display the specific error message to the user
const numField = document.querySelector('#num');
const messageBox = document.querySelector('#messagebox');
numField.addEventListener('input', function(event) {
const value = event.target.value
const isValid = (numField.validity.valid);
if(isValid) {
// Don't show message box if input is valid.
messageBox.style.display = 'none';
messageBox.textContent = '';
} else {
// show message box if input is invalid
messageBox.style.display = 'block';
let errorMessage = '';
if(numField.validity.rangeOverflow) {
errorMessage += 'The number is too long. ';
}
if(numField.validity.rangeUnderflow) {
errorMessage += 'The number is too short. ';
}
if(numField.validity.stepMismatch) {
errorMessage += 'The number is not allowed. ';
}
if(numField.validity.valueMissing) {
errorMessage += 'The number field is required';
}
messageBox.textContent = errorMessage;
messageBox.style.color = 'red';
}
})
To validate the number field, we first used the context validation API to check if the input field is valid.
If the input field is not valid, we then check for the specific item that makes it invalid.If the number typed in the input field is less than the minimum value, in this case 10, the message box will be displayed showing the error message The number is too short.
Similar cases will happen for numbers that are greater than 20.
Also, since the input field is required, when the user has not supplied any number, then the validation error will be valueMissing.
If that is the case, we tell the user that the number field is required.
Below is a demo of this input field being validated.
Conclusion
Using the context validation API, we can validate quite a number of edge case. But our forms will be more resilient when we combine the context validation API with some custom validation of ours.
The code sample used here can be found on Github. To learn more about the context validation API, take a look at this tutorial.