How to check if a checkbox is checked in JavaScript?
Use the checked property to see if a checkbox is ticked, get all checked values in a group, and avoid the checked attribute, which shows the initial state.
Read the checked property of the input. It's true when the box is ticked and false when it isn't.
<input type="checkbox" id="terms" name="terms">
<label for="terms">I accept the terms</label>const terms = document.querySelector('#terms');
if (terms.checked) {
console.log('Terms accepted');
}To react when the user ticks or unticks the box, listen for the change event:
const submitButton = document.querySelector('.signup-button');
terms.addEventListener('change', (event) => {
submitButton.disabled = !event.target.checked;
});change only fires when the user changes the box. Setting terms.checked = true in your code doesn't trigger it. In React it's the same property: read event.target.checked in onChange.
Get all checked boxes in a group
Checkboxes that belong together share a name:
<form class="newsletter">
<label><input type="checkbox" name="topics" value="css"> CSS</label>
<label><input type="checkbox" name="topics" value="html"> HTML</label>
<label><input type="checkbox" name="topics" value="react"> React</label>
</form>Select the checked ones with the :checked pseudo-class and map them to their values:
const checked = document.querySelectorAll(
'input[name="topics"]:checked'
);
const topics = [...checked].map((input) => input.value);
// ['css', 'react']Or let FormData collect them. getAll always returns an array, and it's empty when nothing is checked:
const form = document.querySelector('.newsletter');
const topics = new FormData(form).getAll('topics');
// ['css', 'react']Unchecked boxes aren't included in FormData at all, and a checked box without a value attribute gives 'on'. That's also exactly what the server receives when the form is submitted.
Gotcha: the checked attribute is only the starting state
// <input type="checkbox" id="terms">, then the user ticks it
terms.checked; // true
terms.hasAttribute('checked'); // false
terms.getAttribute('checked'); // null
terms.defaultChecked; // falseThe checked attribute in the HTML sets the initial state, and the defaultChecked property mirrors that attribute. Clicking the box changes the checked property, not the attribute. So getAttribute('checked'), hasAttribute('checked') and the [checked] selector all tell you how the page loaded, which is also the state a form reset goes back to. Read the property. In old jQuery code, that's the difference between .prop('checked') and .attr('checked').
If you want a box ticked when the page loads, see how to check a checkbox or radio button by default.
indeterminate is a property only
A checkbox can also look half-checked, like a "select all" box when only some items are selected. There's no HTML attribute for that state. Set the indeterminate property from JavaScript:
const selectAll = document.querySelector('#select-all');
const boxes = document.querySelectorAll('input[name="topics"]');
const count = [...boxes].filter((box) => box.checked).length;
selectAll.checked = count === boxes.length;
selectAll.indeterminate = count > 0 && count < boxes.length;indeterminate only changes how the box looks. checked still decides what gets submitted, and when the user clicks the box, the browser sets indeterminate back to false.
The CSS side: :checked
If all you need is a visual change, you don't need JavaScript. :checked matches the current state, just like the property:
input:checked + label {
font-weight: 600;
}
.plan:has(input:checked) {
border-color: #2563eb;
}The second rule styles a whole card when the checkbox inside it is ticked. There's also :indeterminate for the half-checked state.