Form validation
Introduction
Section titled “Introduction”The first rule of web development is simple: never trust any user input.
This is because users can enter anything they want into a form field, and it’s up to you to make sure that the data is valid and safe to use.
This tutorial will walk you through how to validate user input in a sign-up form for Harmony Music Academy.
1. Presence checking
Section titled “1. Presence checking”The simplest form of validation is to check if a field is empty or not. This is known as presence checking.
In our sign-up form, we want to make sure that the user has entered their email address, level, and hours per week.
Checking for empty fields
Section titled “Checking for empty fields”Let’s start by seeing what happens when we submit the form without entering any data.
-
If you have been following the steps in the previous tutorial on Capturing Form Data, you should already have the following code inside your
index.jsfile:index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {event.preventDefault();// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = document.querySelector("#hoursPerWeek").value;console.log({ userEmail, userLevel, userHours });});7 collapsed lines// Validate the user's input// Check if the user has selected a level// Check if the user has provided an email address// Check if the user has specified at least one hour of study// Check if the number of hours requested is within the allowed range// Calculate the total cost// Display the total cost to the user -
With this code in place, start your application server in the usual way.
-
In your browser, open up the dev tools, and navigate to the ‘Console’ tab.
-
Submit the form without entering any data. You should see the following output in the console:

As you can see, the
userEmailanduserHoursvalues are empty strings, whileuserLevelis string that reads'basic'.{ userEmail: "", userLevel: "basic", userHours: "" }
Let’s spend a moment to understand where these values are coming from.
Checking for empty fields
Section titled “Checking for empty fields”Now that we know where our form values are coming from, let’s think how we can add a validation check that ensures that the user has entered an email address.
-
Inside
index.js, just above theconsole.log()statement, add a conditional check like so:index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {event.preventDefault();// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = document.querySelector("#hoursPerWeek").value;// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}console.log({ userEmail, userLevel, userHours });}); -
Save your changes, and head back over to your browser.
Make sure your devtools console is still open, and try submitting an empty form again.
This time, you should see an alert message that says “Please enter your email address.”

-
Did you notice something else as well? The
console.log()statement is no longer executed when the email field is empty.Can you work out why?
Solution
Section titled “Solution”This is because the
returnstatement inside theifblock stops the function from executing any further.if (userEmail === "") {alert("Please enter your email address.");return;}Any time you see a
returnstatement inside a function, it means that the function will stop executing the code inside it at that point andreturnwhatever value we have told it to.(In this case, the function returns
undefined, because we haven’t specified a value to return.)Because of this, the
console.log()statement is never reached when the email field is empty.This behaviour is useful because it allows us to stop the computer processing data unnecessarily if any of the fields are empty.
Click to reveal -
Now that we have a check in place for the email field, let’s add similar ones to validate the other form fields.
Move the next two steps of your comment plan up inside the event handler function:
index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {8 collapsed linesevent.preventDefault();// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = parseInt(document.querySelector("#hoursPerWeek").value);// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}// Check if the user has selected a level// Check if the number of hours requested is within the allowed rangeconsole.log({ userEmail, userLevel, userHours });});// Check if the user has selected a level// Check if the number of hours requested is within the allowed rangeCan you add checks to ensure that the
userLevelanduserHoursfields are not submitted as empty strings? 🤔Expected behaviour
Section titled “Expected behaviour”- If the user has submitted an empty string for either
userHoursoruserLevel, display an alert message to prompt them to enter the required information. - The function should not continue to log the form data to the console if
userEmail,userHoursoruserLevelare empty. - If there are values for each of the fields, the form data should be logged to the console as before.
Solution
Section titled “Solution”To add checks for the
userHoursanduserLevelfields, you can follow the same pattern as the check for theuserEmailfield.index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {8 collapsed linesevent.preventDefault();// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = parseInt(document.querySelector("#hoursPerWeek").value);// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}// Check if the user has selected a levelif (userLevel === "") {alert("Please select a level of study");return;}// Check if the user has specified at least one hour of studyif (userHours === "") {alert("Please enter at least one hour of tuition.");return;}console.log({ userEmail, userLevel, userHours });});// Check if the user has selected a level// Check if the number of hours requested is within the allowed range// Calculate the total cost// Display the total cost to the userClick to reveal - If the user has submitted an empty string for either
2. Content validation
Section titled “2. Content validation”Presence checking is one thing, but we also need to make sure that the data entered by the user is valid.
Let’s start by checking if the user has entered a valid email address.
Checking for valid email addresses
Section titled “Checking for valid email addresses”This is actually surprising easy!
-
Open
index.html -
Locate the input field for the user’s email address.
It should be around line 17, and look like this:
index.html <inputid="email"name="email"type="text"class="form-input"placeholder="Your email"/> -
The
typeattribute of the input field is set totext, which means that it accepts any kind of text input.All we need to do is change this to
email:index.html <inputid="email"name="email"type="email"class="form-input"placeholder="Your email"/> -
With this in place, if you submit a value in the email field that is not a valid email address, the browser will automatically display an error message.

Checking for valid hours
Section titled “Checking for valid hours”One surprisingly tricky check is to ensure that users must enter a positive integer for the number of hours.
-
Open
index.js -
Before we can check if the number is positive or not, we need to convert the value of
userHoursto a number.This is because the
valueof an input field is always a string, even if the HTML input field is of typenumber.To convert the value to a number, we can use the built-in JavaScript
parseInt()function.Remove the line highlighted in red below, and replace it with the code highlighted in green:
index.js form.addEventListener("submit", function (event) {event.preventDefault();let userEmail = document.querySelector("#email").value;let userLevel = document.querySelector("#level").value;let userHours = document.querySelector("#hoursPerWeek").value;let userHours = document.querySelector("#hoursPerWeek").value;let userHours = parseInt(document.querySelector("#hoursPerWeek").value);12 collapsed linesif (userEmail === "") {alert("Please enter your email address.");return;}if (userHours === "") {alert("Please enter at least one hour of tuition.");return;}console.log({ userEmail, userLevel, userHours });}); -
Now we can check whether the actual value is a positive number. But this is where it gets tricky.
Our previous solution of checking if the value is an empty string will no longer work, because
parseInt()always returns a number, even if the user enters an empty string.The problem is that an empty string cannot be converted to a number, so
parseInt()will instead returnNaN(Not a Number) instead.As a result, our previous presence check which looks at whether
userHours === ""will no longer work, so we need to update it.Remove the previous check, and modify it as follows:
index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {event.preventDefault();20 collapsed lines// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = parseInt(document.querySelector("#hoursPerWeek").value);// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}// Check if the user has selected a levelif (userLevel === "") {alert("Please select a level of study");}// Check if the user has specified at least one hour of studyif (userHours === "") {if (isNaN(userHours) || userHours < 1) {alert("Please enter at least one hour of tuition.");return;}console.log({ userEmail, userLevel, userHours });});// Check if the number of hours requested is within the allowed range// Calculate the total cost// Display the total cost to the user -
Save your changes, and head across to your browser.
Try submitting the form with an empty hours field, and then again with
0or a negative number.In each case, should see the following alert message:

Validate level and hours
Section titled “Validate level and hours”There are at least two more validation checks we need to consider:
- Is the level of study selected by the user valid?
- Is the number of hours requested within the allowed range for the level they have chosen (e.g., between 1 and 10 hours)?
Can you implement these two checks in your code?
Discuss this with a partner or in a group first, and then try to implement the checks in your code.
Are there any other validation checks that you identified while planning your logic algorithm?
Expected behaviour
Section titled “Expected behaviour”- If any validation check fails, display an alert message to prompt the user to enter the required information.
- The function should not continue to log the form data to the console if any of the validation checks fail.
- If all validation checks pass, the form data should be logged to the console as before.
Solution
Section titled “Solution”-
Validating with an object
Section titled “Validating with an object”There are several ways to do this, but one of the most efficient and scaleable is to use an object.
Place this object at the top of your event listener:
index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {event.preventDefault();const maxHoursPerLevel = {basic: 5,advanced: 10,};29 collapsed lines// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = parseInt(document.querySelector("#hoursPerWeek").value);// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}// Check if the user has selected a levelif (userLevel === "") {alert("Please select a level of study");}// Check if the user has specified at least one hour of studyif (isNaN(userHours) || userHours < 1) {alert("Please enter at least one hour of tuition.");return;}console.log({ userEmail, userLevel, userHours });});// Calculate the total cost// Display the total cost to the user -
Now, just below the check for the number of hours, add the validation code that ensures the level selected is valid, and that the number of hours requested is within the allowed range:
index.js // Capture user's input on form submissionlet form = document.querySelector("form");form.addEventListener("submit", function (event) {event.preventDefault();const maxHoursPerLevel = {basic: 5,advanced: 10,};26 collapsed lines// Store the user's email address as userEmail (string/text)let userEmail = document.querySelector("#email").value;// Store the user's level as userLevel (string/text)let userLevel = document.querySelector("#level").value;// Store the user's hours of study as userHours (number)let userHours = parseInt(document.querySelector("#hoursPerWeek").value);// Validate the user's input// Check if the user has provided an email addressif (userEmail === "") {alert("Please enter your email address.");return;}// Check if the user has selected a levelif (userLevel === "") {alert("Please select a level of study");}// Check if the user has specified at least one hour of studyif (isNaN(userHours) || userHours < 1) {alert("Please enter at least one hour of tuition.");return;}// Is userLevel valid?if (!maxHoursPerLevel.hasOwnProperty(userLevel)) {alert("Invalid level of study selected.");return;}// Is userHours within range?const maxAllowedHours = maxHoursPerLevel[userLevel];if (userHours > maxAllowedHours) {alert(`You can only study a maximum of ${maxAllowedHours} hours per week.`);return;}console.log({ userEmail, userLevel, userHours });});// Calculate the total cost// Display the total cost to the user -
This is approach is most efficient because it allows you to easily add more levels and their corresponding maximum hours without having to change the validation code.
Likewise, the
maxHoursPerLevelobject doubles as a reference for valid levels, as each key in the object corresponds to a valid level of study.
Summary
Section titled “Summary”In this tutorial, you learned how to validate user input in a sign-up form for Harmony Music Academy.
We have covered:
- Presence checking to ensure that the user has entered data in all required fields.
- Content validation to ensure that the data entered is of the correct type and format.
- Using a
returnstatement to stop the function from executing if any validation check fails.
Next steps
Section titled “Next steps”In the next step, we will learn how to optimise the error messages shown to users when they fail to complete the required information.