Using the HTML Checkbox ✅ and Managing the Check State ✔ with JavaScript [Tutorial]
Checkboxes are a fundamental input component typically represented by an empty box in the unselected state and a box with a checkmark (hence the checkbox name) when selected. They are used to represent a boolean choice, each correlating to a value choice.
Managing checkboxes in HTML, specifically using JavaScript and jQuery can seem a bit unnatural. I hope to resolve common problems you may be having with this tutorial.
Checkboxes are good to use when you need to collect either a true/false (boolean) choice or multiple values from a list of options.
Radio buttons offer a similar boolean selection metaphor, but are used when there is a single choice available within a list.
There are two general use cases for a checkbox:
- When You Need Confirmation or Acknowledgement, for example acknowledging a terms of use
- When Multiple Values Can Answer a Single Question
Checkboxes are used for instances where a user may wish to select multiple options, such as in the instance of a "check all that apply" question. HTML Checkboxes Selected. A checkbox element can be placed onto a web page in a pre-checked fashion by setting the checked attribute with a "yes" value.
The Correct HTML For Making a Checkbox
There seems to be confusion over the proper or correct way to write checkbox html. I have been there too, so I empathize with everyone.
As far as the checkbox user interface you should include a checkbox and label element, in that order. This will naturally place the checkbox to the left of the label.
If you need to swap their order you can either by swapping their html or using CSS. However, I will caution you again that unless you know you can keep related or grouped checkboxes horizontally aligned.
By nature checkboxes are small targets, which for the desktop and mouse is normal, but in today's mobile, touch first world can be problematic.
The good news is you can relate a checkbox's label to the checkbox, extending the actionable area the user can click or touch to toggle the check state.
This is done by adding either a 'name' or 'id' attribute to the checkbox element and a corresponding 'for' attribute to the label. The label's for attribute value should match the checkbox's name or id value.
The Value Property or Attribute
Programatically you can get the current value or check state from the value property, which is also an attribute. The value is not true or false, even though the nature of the checkbox is to indicate if a value is selected or not.
var btnSubscribe = document.getElementById("btnSubmitSubscribe"); btnSubscribe.addEventListener("click", function (evt) { evt.preventDefault(); var subscribe = document.querySelector("[name=subscribe]"); console.log(subscribe.value); //writes 'newsletter' return false; });
You can get the value property independent of the checked state. So make sure you add the logic to your validation and serialization code to account for this behavior.
Rendering Checkboxes Checked By Default
When rendering a page with a checkbox you want selected or checked by default you need to include the 'checked' attribute. There is no required value for the checked attribute.
However, per the checkbox specification only an empty value or 'checked' are valid.
When checked is added to the checkbox element the browser will render it as selected.
How to Detect if a CheckBox Was Checked?
When a form is submitted or serialized a checkbox's value is associated with the name of the checkbox. It is the responsibility of the server to handle this key/value relationship. This is when a form is posted directly to a target URL using form encoding.
When using form encoding checkboxes of the same name values are all serialized:
mininterest=javascript&mininterest=html
You are responsible for handling the form submission on the server. Since there are hundreds of platforms I wont even try to demonstrate that in this article.
If a checkbox in unchecked the corresponding value is not serialized.
When you are handling the serialization in your JavaScript you are responsible for this serialization. I generally intercept any form submission and perform validation and serialization before posting JSON to an API,which means I need to handle these scenarios.
function validateInterest(evt) { evt.preventDefault(); var mininterest = document.querySelectorAll("[name=mininterest]"); var count = 0, interests = []; for (var i = 0; i < mininterest.length; i++) { if (mininterest[i].checked) { count++; interests.push(mininterest[i].value); } } //This is meant to mimic where you would make a fetch POST call if (count > 1) { addToLog("enough interests selected: " + interests); } else { addToLog("**NOT ENOUGH** interests selected: " + interests); } return false;}
The best practice is to serialize the selected values in an array. You could make a more complex structure if needed, but I think an array should handle just about all cases.
The checkbox value property is not required. If no value is used when submitted the value is set to 'on' if the input is selected. If the checkbox is not selected there is not value supplied. This means your server-side processing code needs to be robust enough to handle this null or empty state.
Handling the Checkbox State Change Events
You want to trigger a real-time response to a change in checked state. You can do this by binding an event handler to the checkbox's change event.
function bindStateChanges(){ var interests = document.querySelectorAll("[name=interest"); for (var index = 0; index < interests.length; index++) { interests[index].addEventListener("change", function(evt){ var checkbox = evt.target; addToLog(checkbox.value + " changed to " + checkbox.checked); }); }}
Here I bound event handlers to all checkboxes with the name 'interest'. I am simply logging the activity to the page to demonstrate handling the change. You would want to add your own logic in the handler.
Grouping Checkboxes
As I have already mentioned checkboxes specialize is collecting a single value choice. But what about needing a choice of many options?
This is where the checkbox becomes even better, through grouping. Here you have two or more checkboxes with the same name, but different values. We have already seen how this can be used in the previous examples.
In this example both checkboxes chare the name 'interest' but have unique id and value values.
Defining a Large Hit or Touch Area
Checkboxes are small targets. With the rise of Smartphones and touch screens small targets are a problem. Small targets are also a problem for assitive technologies and users with poorer eyesight.
This is why you should always associate the checkbox's label with the checkbox. The touch area is not limited to just the checkbox's immediate rectangle, but also includes the associated label's rectangle when they are associated.
I also think this is a best practice because many users first attempt to tap and click the label instead of the checkbox. I think this is becaue they assume, on a touch screen specifically they are a single button. Of course this is just my opinion, but based on observation and conversation with typical end users.
You associate a label with a checkbox with the 'for' attribute. The checkbox should include a unique id value. The label's for value should match the checkbox's id value.
Because checkboxes are often done as a list you should craft some sort of unique naming convention. For example, a spaghettie and meatball grocery list might use:
- 'spaghettie-meatballs-spaghettie'
- 'spaghettie-meatballs-meatballs'
- 'spaghettie-meatballs-sauce'
Notice how each one start with the same value, 'spaghettie-meatballs-'? This helps logically group the related checkboxes. The unique value is the id's suffix value, which correlates to the value property.
Just be sure to what I call slugify the id values if you are generating them automatically. By this I mean removing spaces and 'odd' characters. Just use common characters, dashes and underscores. And don't forget to make the server smart enough to use these values!
The Indeterminate State
There is a third state a checkbox can be in beside checked and unchecked, indeterminate. This can only be set via JavaScript and causes the checkbox to render with a horizontal line in the box instead of just a box or a box with a check.
You may be wondering when you might want to use this state?
The indeterminiate state is commonly used when there are multiple child or sub-options available. You can set the state to indeterminate when a minimal number of child options are not selected.
function setupIndeterminate() { var pickInterest = document.querySelectorAll("[name=pickInterest"), parentInterest = document.getElementById("pickInterests"); for (var index = 0; index < pickInterest.length; index++) { var cb = pickInterest[index]; cb.addEventListener("change", function (evt) { var checked = 0; for (var j = 0; j < pickInterest.length; j++) { if (pickInterest[j].checked) { checked++; } } switch (checked) { case 0: parentInterest.checked = false; parentInterest.indeterminate = false; break; case 1: parentInterest.checked = false; parentInterest.indeterminate = true; break; default: parentInterest.checked = true; parentInterest.indeterminate = false; break; } }); }}
This scenario could use an indeterminate enabled checkbox as a visual queue or part of a select/deselect all UI.
You could pair the logic setting indetermine with your form validation logic. Often when a checkbox is in indeterminate state the form is not yet complete, so you can enforce your form validation logic accordingly.
If the form is submitted while in indeterminate state it is serialized as unchecked.
Summary
I hope this has help clear up some common questions you may have about using the HTML checkbox. This is one of the original HTML elements and has retained most of its original capabilities, but as with anything web we have grown to make checkboxes do much more.
Be sure to read upcoming articles on how to create custom styled checkboxes so you wont be limited to the boring check in the box UI!