HTML forms are essential components of most websites and web apps. They enable interaction between users and those websites, and are a key concept for web developers to understand.
This comprehensive guide covers various aspects of HTML forms, from how to create and structure forms to JavaScript interaction and form validation.
Understanding how to work with forms programmatically allows you to validate and capture user input, handle submissions, and enhance the overall user experience.
By following the examples and best practices provided in this guide, you’ll be equipped with the knowledge necessary to build robust web forms that enhance user experience and facilitate seamless data collection and submission.
Whether you’re a beginner or an experienced developer, this guide serves as a valuable resource for understanding and implementing HTML forms effectively in your web projects.
Prerequisites:
A basic understanding of JavaScript fundamentals is recommended to fully comprehend the concepts discussed in this tutorial. Familiarity with HTML forms will also be beneficial for understanding and applying the material covered.
If you’re new to JavaScript, it’s recommended to acquaint yourself with variables, data types, functions, loops, and basic DOM manipulation techniques before diving into this tutorial. This foundational knowledge will facilitate a smoother learning experience as we explore more advanced topics related to form handling in JavaScript.
Starting Note: For your convenience, all the examples and code discussed here can be accessed on GitHub.
Table of Contents
- Understanding HTML Forms
– Introduction to HTML form elements
– JavaScript and Form Handling
– Accessing Form Fields
– Example: Registration Form
- How to Create Radio Buttons
– JavaScript to Handle Radio Button Selection
– Radio Button Change Event
- Checkboxes
– How to Check if a Checkbox is Checked
– How to Get Checkbox Values
– How to Handle Multiple Checkboxes
– How to Check / Uncheck All Checkboxes
– How to Dynamically Generate CheckBoxes
- Select Element
– How to Interact with a Select Element
– How to Access Options with JavaScript
– How to Handle Multiple Selections
– Example: Task Manager
- Difference Between Change and Input Event
- Conclusion
Before we start, here’s something to note:
This is a follow up blog on this DOM and Events Handbook and not cover server-side communication/server-side form handling in this blog as it involves advanced topics such as AJAX (Asynchronous JavaScript and XML), Promises, error handling, and handling asynchronous operations in JavaScript.
In this tutorial, we’ll instead focuses on how to work with various form elements including radio buttons, checkboxes, and select elements, as well as dynamically generating and interacting with them using JavaScript.
Delving into server-side communication would extend beyond the scope of this article, which aims to provide a comprehensive understanding of DOM manipulation and event handling within the context of form elements.
HTML forms are fundamental elements used for collecting and submitting user data on the web. They enable interaction between users and websites by allowing users to input information, make selections, and submit data to servers for processing.
HTML forms are created using the <form>
element, which acts as a container for various input elements. Common form elements include text fields, checkboxes, radio buttons, dropdown menus, and buttons.
To reference a form in JS, you can use DOM methods like getElementById()
or document.forms
. document.forms
returns a collection of forms, and you can access a specific form using an index, name, or id.
const form = document.getElementById('signup');const firstForm = document.forms[0]; // accessing first formconst formByName = document.forms['formName']; // accessing form by nameconst formById = document.forms['formId']; // accessing form by id
Let’s see a basic example of an HTML form:
<form> <label for="username">Username:</label> <input type="text" id="username" name="username"><br> <label for="password">Password:</label> <input type="password" id="password" name="password"><br> <input type="submit" value="Submit"></form>
In this example, we have a form with two input fields for username and password, along with a submit button.
HTML forms can have various attributes that control their behavior and appearance. Some common attributes include:
- action: Specifies the URL where the form data should be submitted.
- method: Specifies the HTTP method used to send form data (
post
or get
).
- target: Specifies where to display the response after form submission (for example,
_self
, _blank
, _parent
, _top
).
- name: Assigns a name to the form for identification purposes.
Here’s an example of a form with action, method, and target attributes:
<form action="/submit-form" method="POST" name="myForm" target="_blank"> <!-- Form elements go here --></form>
JavaScript uses the HTMLFormElement
object to represent a form. This object has properties corresponding to the HTML attributes action
and method
.
Methods like submit()
and reset()
are used for submitting and resetting forms.
const form = document.getElementById('signup');form.action; // returns the action attributeform.method; // returns the method attributeform.submit(); // submits the form
JavaScript provides Event Handlers to add interactivity to HTML forms. By leveraging these events, you can execute custom scripts in response to user actions within the form:
Submit Event: A form typically has a submit button, which when clicked, sends the form data to the server. This is achieved using an <input>
or <button>
element with type="submit"
.
<input type="submit" value="Sign Up">// or<button type="submit">Sign Up</button>
To attach an event listener to the submit event, you use the addEventListener()
method. Here’s an example:
const form = document.getElementById('signup');form.addEventListener('submit', (event) => { // Custom validation and submission logic here});
In many cases, you may want to intercept the default form submission behavior and execute custom logic before allowing the form to be submitted to the server. You can use preventDefault()
for this. Example:
const form = document.getElementById('signup');form.addEventListener('submit', (event) => { event.preventDefault(); // Prevents the default form submission // Custom validation and submission logic here});
Without event.preventDefault()
, any custom validation and submission logic would still execute within the event listener, but the default form submission behavior would not be prevented.
Reset Event: The reset
event is triggered when the form is reset using a reset button or programmatically. We use reset()
method to clear all form fields and reset them to their default values.
document.querySelector('form').addEventListener('reset', function(event) { // Custom form reset logic here});
You can access form fields using DOM methods like getElementsByName()
, getElementById()
, querySelector()
, and so on
The form.elements
property stores a collection of form elements. You can access these Elements by index, id, or name. Here’s an example:
const form = document.getElementById('signup');const nameField = form.elements['name']; // accessing element by nameconst emailField = form.elements['email']; // accessing element by nameconst firstElement = form.elements[0]; // accessing first element by index no.
Once you’ve accessed a form field, you can use the value
property to access its value. Here’s an example:
const nameValue = nameField.value;const emailValue = emailFieldByName.value;
Form validation is an essential aspect of web development that ensures the data submitted by users is accurate and meets specified criteria before being processed by the server. Common validations include checking for empty fields, valid email formats, and so on.
HTML5 provides built-in form validation through various attributes:
- required: Specifies that a field must be filled out.
- pattern: Specifies a regular expression pattern that the input value must match.
- min and max: Specify the minimum and maximum values for an input field.
- maxlength and minlength: Specify the maximum and minimum length of the input
- type: Specifies the type of input expected (for example, email, number, date).
Here’s an example of HTML form validation using these attributes:
JavaScript allows developers to perform more sophisticated validation logic beyond what HTML attributes offer. Event listeners can be attached to form elements to handle validation dynamically.
Here’s a basic example of JavaScript form validation:
const form = document.querySelector('form');form.addEventListener('submit', function(event) { event.preventDefault(); // Prevent form submission // Perform custom validation logic const email = document.getElementById('email').value; const password = document.getElementById('password').value; if (!emailIsValid(email)) { alert('Please enter a valid email address.'); return; } if (password.length < 6) { alert('Password must be at least 6 characters long.'); return; } // If validation passes, submit the form form.submit();});function emailIsValid(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}
In this example, the JavaScript function emailIsValid()
uses a regular expression to validate the email format. The submit
event listener prevents the form from being submitted if the validation fails, and custom error messages are displayed to the user.
Now, let’s combine all the concepts we’ve covered into a complete example of a Registration form with client-side validation using JavaScript:
<!DOCTYPE html><html> <body> <h2>User Registration</h2> <form id="registrationForm"> <div> <label for="username">Username:</label> <input type="text" id="username" name="username" /> </div> <div> <label for="email">Email:</label> <input type="email" id="email" name="email" /> </div> <div> <label for="password">Password:</label> <input type="password" id="password" name="password" /> </div> <div> <input type="submit" value="Register" /> </div> </form> <div id="errorMessages"></div> <script src="script.js"></script> </body></html>
HTML Structure: We have a simple registration form with fields for username, email, password, and a submit button. There’s also a container div (errorMessages
) to display validation error messages.
Now let’s write JavaScript code to handle form submission and perform client-side validation:
const registrationForm = document.getElementById("registrationForm");const errorMessages = document.getElementById("errorMessages");registrationForm.addEventListener("submit", function (event) { event.preventDefault(); const { username, email, password } = registrationForm.elements; errorMessages.innerHTML = ""; if (!username.value.trim()) { displayError("Username is required."); return; } if (!email.value.trim() || !isValidEmail(email.value)) { displayError("Please enter a valid email address."); return; } if (!password.value.trim() || !isStrongPassword(password.value)) { displayError( "Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character." ); return; } alert("Registration successful!"); registrationForm.reset();});function displayError(message) { errorMessages.innerHTML += `<div class="error">${message}</div>`;}function isValidEmail(email) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}function isStrongPassword(password) { return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$/.test(password);}
JavaScript Handling: We select the form and the error message container using getElementById
. We attach an event listener to the form’s submit event. When the form is submitted, we prevent its default behavior using event.preventDefault()
to handle form submission manually.
Form Validation: We retrieve the values of username, email, and password.
We perform basic validation: Username must not be empty, Email must be in a valid format, Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one digit, and one special character.
Error Handling: If any validation fails, we display the corresponding error message. Error messages are displayed in the errorMessages
div.
Form Reset: Upon successful registration (in this case, a simple alert), we reset the form using registrationForm.reset()
Currently, the code uses an alert
to indicate successful registration. In a real scenario, you might want to implement an AJAX call to submit the data to a server for processing and handle the response accordingly But that’s not what we’re going to discuss, as mentioned at the start of this tutorial.
Overall this example covers form creation, form handling with JavaScript, form validation using regular expressions, and dynamic custom error message display, demonstrating a basic user registration form with client-side validation.
Radio buttons are a common form element used to select one option from a set of options. In JavaScript, you can manipulate radio buttons to retrieve user selections and perform actions based on those selections.
You can use radio buttons you want users to select only one option from a set of choices. In HTML, you can create radio buttons using the <input>
element with the type
attribute set to “radio”. A group of radio buttons with the same name
attribute forms a radio group.
Here’s an example:
You use the id
and for
attributes for accessibility, linking the label to the corresponding radio button.
Now, let’s discuss how to retrieve the value of the selected radio button using JavaScript.
Here’s how this the code works: the JavaScript code initializes by selecting the button, radio buttons, and output elements from the HTML document. We add a click event listener to the button element. When the button is clicked, the function inside the event listener is executed.
Inside the click event listener, we iterate over all radio buttons in the radioButtons
collection. We check if a radio button is checked using its checked
property. If a radio button is checked, we assign its value to the selectedLanguage
variable and exit the loop using break
.
We update the content of the output element (<p>
tag with id output
) based on whether a language is selected. If a language is selected (selectedLanguage
is truthy), we display a message indicating the selected language. Otherwise, we prompt the user to select a language.
When a radio button is checked or unchecked, it fires a change
event. You can listen to this event using addEventListener()
. Inside the event handler, you can access the checked state and value of the radio button using this.checked
and this.value
.
radioButton.addEventListener('change', function (e) { if (this.checked) { console.log(this.value); }});
Now, let’s explore how to dynamically generate radio buttons using JavaScript. This is useful when you want to create radio button options dynamically based on certain criteria or data.
Suppose we have an array of languages, and we want to dynamically generate radio buttons for each language option:
It dynamically generates radio buttons based on the languageOptions
array and inserts them into the container element (<div id="languages"></div>
). Each radio button has a unique ID and value corresponding to the language name, and the labels are associated with their respective radio buttons using the for
attribute.
After dynamically generating the radio buttons, Now let’s add change
event listeners to them to handle changes in selection.
<!-- HTML --> <div id="languages"></div> <div id="languageOutput"></div> // we create this one to fetch our selected language output <!-- Generate the radio buttons -->// Attaching Change Event Listenersconst radioButtons = document.querySelectorAll('input[name="language"]');for (const radioButton of radioButtons) { radioButton.addEventListener('change', showSelectedlanguage);} // Handling the Change Eventfunction showSelectedlanguage() { if (this.checked) { document.querySelector('#languageOutput').innerText = `You selected ${this.value}`; }}
Here’s what’s happening:
- We select all radio buttons with the
name
attribute set to "language"
.
- We use a
for...of
loop to iterate over each radio button and add a change
event listener to each radio button. This listener listens for changes in the state of the radio buttons, i.e., when a radio button is selected or deselected.
- We define a function named
showSelectedLanguage
to handle the change event triggered by selecting a radio button.
- Inside the
showSelectedLanguage
function, we first check if the current radio button (this
) is checked using the checked
property. If the radio button is checked, we update the text content of an element with the id languageOutput
using document.querySelector('#languageOutput')
. This element serves as a placeholder to display the selected language.
This setup ensures that dynamically generated radio buttons have change
event listeners attached to them, allowing for dynamic handling of user selections.
Checkboxes
How to Create an HTML Checkbox
Let’s first create a checkbox using the <input>
element and type attribute set to “checkbox”. let’s associate it with label for better accessibility.
<label for="agree"> <input type="checkbox" id="agree" name="agree" value="yes"> I agree to the terms</label>
How to Check if a Checkbox is Checked
A checkbox in HTML can exist in two states: checked and unchecked. And we can determine which is active using checked
property. If it’s true
, the checkbox is checked – otherwise, it’s unchecked. Example:
How to Get Checkbox Values
In HTML forms, when a checkbox is checked and the form is submitted, the browser includes the checkbox in the form data with its name
attribute as the key and the value
attribute (if specified) as the value. But if the checkbox is unchecked, it’s not included in the form data at all.
So basically the point is: When a checkbox is checked and included in form submissions, the browser defaults to sending 'on'
as the value if no value
attribute is explicitly defined for the checkbox input element. To accurately handle the checked state of a checkbox using JavaScript, use the checked
property instead of relying solely on the value
attribute.
How to Handle Multiple Checkboxes
Sometimes, you may need to work with multiple checkboxes with the same name and you want to retrieve the values of the selected checkboxes. Here’s an example:
In this example, we have checkboxes for selecting preferred programming languages.
- When the button is clicked, it triggers an event listener. Inside the event listener, we select all checkboxes with the name attribute “language” that are checked.
- We then convert the NodeList returned by
querySelectorAll()
into an array using Array.from()
.
- Finally, we map over the array to retrieve the values of selected checkboxes and display them using
alert()
.
How to Check / Uncheck All Checkboxes
Now, let’s create a functionality to check or uncheck all checkboxes at once:
<!DOCTYPE html><html> <body> <p> <button id="btn">Check / Uncheck All</button> </p> <p>Select your preferred languages:</p> <label for="l1"> <input type="checkbox" name="language" value="C++" id="l1" />C++ </label> <label for="l2"> <input type="checkbox" name="language" value="Python" id="l2" />Python </label> <label for="l3"> <input type="checkbox" name="language" value="Java" id="l3" />Java </label> <script src="script.js"></script> </body></html>
Javascript code:
// function to check or uncheck all checkboxesfunction check(checked = true) { const checkboxes = document.querySelectorAll('input[name="language"]'); // Iterate through each checkbox checkboxes.forEach((checkbox) => { // Set the checked property of each checkbox to the value of the 'checked' parameter checkbox.checked = checked; });}// function to check all checkboxes and change button behavior to uncheck allfunction checkAll() { check(); this.onclick = uncheckAll;}// function to uncheck all checkboxes and change button behavior to check allfunction uncheckAll() { check(false); this.onclick = checkAll;}const btn = document.querySelector("#btn");btn.onclick = checkAll;
In this example, we have a button labeled “Check / Uncheck All”.
- When the button is first clicked, it’s intended to check all the checkboxes. Therefore, the
checkAll
function is assigned to handle this action (const btn = document.querySelector("#btn");
).
- If the button is clicked again, it unchecks all checkboxes. We define functions
check()
, checkAll()
, and uncheckAll()
to handle the checking and unchecking of checkboxes.
- We assign
checkAll()
to the button’s onclick
event initially, and then switch between checkAll()
and uncheckAll()
based on the current state of the checkboxes.
Alternate approach could be:
function checkAll(checked = true) { const checkboxes = document.querySelectorAll('input[name="language"]'); checkboxes.forEach((checkbox) => { checkbox.checked = checked; });}const btn = document.querySelector("#btn");btn.addEventListener("click", () => { // Find the first checkbox with the name attribute set to 'language' const firstCheckbox = document.querySelector('input[name="language"]'); // Check if the first checkbox is checked const isChecked = firstCheckbox.checked; // Call the checkAll function with the opposite state of the first checkbox checkAll(!isChecked);});
Here, we select the first checkbox with the name “language” to determine its current checked state. Then, we call checkAll()
with the opposite state.
How to Dynamically Generate CheckBoxes
Here’s how it works:
- We define an array
languageOptions
containing language names.
- We use the
map()
method to iterate through the languageOptions
array and generate an array of HTML strings for each language.
- Each HTML string comprises a
label
element associated with an input
checkbox. The input
checkbox includes appropriate attributes such as type
, name
, id
, and value
, dynamically derived from the language name.
- We join the array of HTML strings into a single string using
join(' ')
.
- Finally, we set the
innerHTML
property of the root <div>
element with the id languages
to the generated HTML string, thereby rendering checkboxes for each programming language.
Select Element:
The <select>
element in HTML provides a dropdown list of options for users to choose from. It allows for single or multiple selections. Example:
By default, a <select>
element allows for a single selection. To enable multiple selections, add the multiple
attribute.
<select id="cities" multiple>
Users can now select multiple fruits by holding down the Ctrl (or Cmd on Mac) key while clicking.
How to Interact with a Select Element:
To interact with a <select>
element using JavaScript, we use the HTMLSelectElement
type, which provides useful properties like selectedIndex
and value
. Example:
JavaScript allows you to handle events on the <select>
element, such as when a user selects an option. Example:
Using the value
property: The value
property represents the value of the selected option. Let’s understand it with example:
<select id="cities"> <option value="">Jaipur</option> <option value="DEL">New Delhi</option> <option value="UDR">Udaipur</option> <option>Mumbai</option></select>
const btn = document.querySelector("#btn");const selectElement = document.querySelector("#cities");btn.onclick = (event) => { event.preventDefault(); alert(selectElement.value);};
- If “Jaipur” is selected, this means we have an empty string since the value attribute is empty in our Html.
- If an option lacks a value attribute, the select box’s value property becomes the text of the selected option. Example: if “Mumbai” is selected, the value property is “Mumbai”.
- If multiple options are selected, the
value
property of the select box is derived from the first selected option based on the previous rules.
How to Access Options with JavaScript
The HTMLOptionElement
type represents individual <option>
elements within a <select>
element in JavaScript. It provides properties like index
, selected
, text
, and value
to access information about each option.
const selectElement = document.getElementById('cities');const secondOptionText = selectElement.options[1].text; // Accessing text of the second optionconst secondOptionValue = selectElement.options[1].value; // Accessing value of the second option
How to Handle Multiple Selections:
When a <select>
element allows multiple selections, you can iterate through its options to find which ones are selected and retrieve their text values.
const selectElement = document.getElementById('cities');const selectedOptions = Array.from(selectElement.options).filter(option => option.selected);const selectedValues = selectedOptions.map(option => option.text);
The output will be an array containing text of selected options. We can use option.value
to get an array of values instead. Example:
<!DOCTYPE html><html> <body> <select id="cities" multiple> <option value="JAI">Jaipur</option> <option value="DEL">New Delhi</option> <option value="UDR">Udaipur</option> <option value="MUM">Mumbai</option> </select> <button id="btn">Get Selected Cities</button> <script> const btn = document.querySelector("#btn"); const selectElement = document.querySelector("#cities"); btn.onclick = (event) => { event.preventDefault(); const selectedOptions = Array.from(selectElement.options) .filter((option) => option.selected) .map((option) => option.text); alert("Selected City: " + selectedOptions.join(", ")); }; </script> </body></html>
- When the button is clicked, the script collects the selected options by filtering the options based on the
selected
property. It then maps over the selected options to retrieve their text content.
- Finally, it displays the selected languages in an alert message.
Let’s See an Example: Task Manager (Adding and Removing Tasks)
<!DOCTYPE html><html> <style> #container { max-width: 540px; margin: 50px auto; } form { display: flex; flex-direction: column; } </style> <body> <div id="container"> <form> <label for="task">Task:</label> <input type="text" id="task" placeholder="Enter a task" autocomplete="off" /> <button id="btnAdd">Add Task</button> <label for="taskList">Task List:</label> <select id="taskList" name="taskList" multiple></select> <button id="btnRemove">Remove Selected Tasks</button> </form> </div> <script src="script.js"></script> </body></html>
This HTML structure includes input fields for entering task descriptions, buttons for adding and removing tasks, and a <select>
element to display the list of tasks. We added a little css for clarity. Let’s see Javascript code now:
const btnAdd = document.querySelector('#btnAdd');const btnRemove = document.querySelector('#btnRemove');const taskList = document.querySelector('#taskList');const taskInput = document.querySelector('#task');btnAdd.onclick = (e) => { e.preventDefault(); // Validate the task input if (taskInput.value.trim() === '') { alert('Please enter a task description.'); return; } // Create a new task option const option = new Option(taskInput.value, taskInput.value); taskList.add(option, undefined); // Reset the task input taskInput.value = ''; taskInput.focus();};btnRemove.onclick = (e) => { e.preventDefault(); // Save the selected tasks let selectedTasks = []; for (let i = 0; i < taskList.options.length; i++) { selectedTasks[i] = taskList.options[i].selected; } // Remove selected tasks let index = taskList.options.length; while (index--) { if (selectedTasks[index]) { taskList.remove(index); } }};
Explaination: we select the necessary elements from the HTML and attach event listeners to the “Add Task” and “Remove Selected Tasks” buttons. When the “Add Task” button is clicked, we create a new task option based on the input field value and add it to the <select>
element. When the “Remove Selected Tasks” button is clicked, we remove the selected tasks from the <select>
element.
The input event in JavaScript is triggered whenever the value of an input, <select>
, or <textarea>
element changes. Unlike the change event, which waits for a value to be committed (for example, when an input loses focus), the input event fires continuously as the value changes. The input event basically provides a way to respond to user input in real-time. Example:
<script> const userInput = document.getElementById('userInput'); const Name = document.getElementById('displayName'); userInput.addEventListener('input', function() { Name.textContent = userInput.value || 'Guest!'; });</script>
- This JavaScript code selects the input field with the ID “userInput” and the span element with the ID “displayName”.
- An event listener is attached to the input event of the userInput field.
- When the input event is triggered (for example, when typing in the input field), the event handler updates the text content of the
displayName
span dynamically to reflect the entered name, or it displays “Anonymous” if the input field is empty.
- Now, if you change ‘input’ to ‘change’ here
userInput.addEventListener('input', function()
like this: userInput.addEventListener('change', function()
, the event listener will be triggered only when the input field loses focus after a value has been entered (as opposed to continuously while the value is being changed in real-time).
Conclusion
By understanding the fundamentals of HTML form elements, attributes, and events, you can create dynamic and user-friendly web forms that enhance the user experience.
JavaScript plays a crucial role in handling form submissions, validating user input, and providing real-time feedback to users.
Through practical examples and detailed explanations, in this guide you’ve learned about working with radio buttons, checkboxes, select elements, and handling multiple selections.
Keep exploring and experimenting with the concepts presented here to create robust and intuitive forms for your web applications.