JavaScript
Checkbox
Web Development
Programming
Front-end Development

Check/Uncheck checkbox with JavaScript

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To check or uncheck a checkbox with JavaScript, set its checked property to true or false. This is the DOM property, not the HTML attribute, and the distinction matters because user interaction modifies the property at runtime while the attribute stays frozen at its initial markup value.

javascript
1const checkbox = document.getElementById('subscribe');
2
3checkbox.checked = true;   // check it
4checkbox.checked = false;  // uncheck it

That single property is the foundation for every checkbox operation you will ever write in plain JavaScript. The rest of this article covers toggling, event handling, group operations, and the patterns that trip developers up most often.

Checking and Unchecking a Single Checkbox

Start with a basic checkbox element in HTML.

html
<input type="checkbox" id="subscribe" />
<label for="subscribe">Subscribe to newsletter</label>

From JavaScript, grab the element and set checked.

javascript
1const checkbox = document.getElementById('subscribe');
2
3// Check it
4checkbox.checked = true;
5
6// Uncheck it
7checkbox.checked = false;

This is the standard browser API. It works in every modern browser and requires no libraries.

Toggling a Checkbox

To flip the current state, negate the property.

javascript
const checkbox = document.getElementById('subscribe');
checkbox.checked = !checkbox.checked;

This pattern is useful when a separate UI element controls the checkbox, such as a button or a keyboard shortcut handler.

html
<input type="checkbox" id="darkMode" />
<label for="darkMode">Dark mode</label>
<button id="toggleBtn">Toggle dark mode</button>
javascript
1const checkbox = document.getElementById('darkMode');
2const toggleBtn = document.getElementById('toggleBtn');
3
4toggleBtn.addEventListener('click', () => {
5    checkbox.checked = !checkbox.checked;
6});

Note that toggling through JavaScript does not fire the change event automatically. If your application relies on change listeners, you need to dispatch the event manually after toggling. More on that below.

Reacting to User Changes with the change Event

When a user clicks a checkbox, the browser fires a change event. Listen for it to run logic in response.

javascript
1const checkbox = document.getElementById('subscribe');
2
3checkbox.addEventListener('change', () => {
4    if (checkbox.checked) {
5        console.log('User subscribed');
6    } else {
7        console.log('User unsubscribed');
8    }
9});

This is the standard pattern for forms, feature toggles, consent banners, and filter UIs. The change event fires only on user interaction by default. If you set checked programmatically and also need the event listener to run, dispatch the event yourself.

javascript
checkbox.checked = true;
checkbox.dispatchEvent(new Event('change'));

Working with Checkbox Groups

Real forms often contain groups of checkboxes. Query them together instead of handling each element individually.

html
<input type="checkbox" class="feature" value="notifications" />
<input type="checkbox" class="feature" value="analytics" />
<input type="checkbox" class="feature" value="exports" />

Check all of them.

javascript
1const boxes = document.querySelectorAll('.feature');
2boxes.forEach(box => {
3    box.checked = true;
4});

Uncheck all of them.

javascript
boxes.forEach(box => {
    box.checked = false;
});

Collect the values of only the checked boxes.

javascript
1const selected = [...document.querySelectorAll('.feature:checked')]
2    .map(box => box.value);
3
4console.log(selected); // e.g., ["notifications", "exports"]

The :checked pseudo-selector is powerful because it lets you query current state directly through querySelectorAll without looping and inspecting each element manually.

Select All / Deselect All Pattern

A "select all" checkbox that controls a group of child checkboxes is one of the most common UI patterns in admin dashboards, email clients, and bulk-action tables.

html
1<input type="checkbox" id="selectAll" />
2<label for="selectAll">Select all</label>
3
4<input type="checkbox" class="row-item" value="1" />
5<input type="checkbox" class="row-item" value="2" />
6<input type="checkbox" class="row-item" value="3" />
javascript
1const selectAll = document.getElementById('selectAll');
2const items = document.querySelectorAll('.row-item');
3
4// When "select all" changes, sync all children
5selectAll.addEventListener('change', () => {
6    items.forEach(item => {
7        item.checked = selectAll.checked;
8    });
9});
10
11// When any child changes, update "select all" state
12items.forEach(item => {
13    item.addEventListener('change', () => {
14        selectAll.checked = [...items].every(i => i.checked);
15    });
16});

The second listener is the part developers forget. Without it, the "select all" checkbox stays checked even after a user unchecks an individual row, which breaks the visual contract.

Property vs. Attribute: Why setAttribute is Wrong

Developers sometimes try to check a checkbox like this.

javascript
// Do NOT use this for runtime state changes
checkbox.setAttribute('checked', 'checked');

This modifies the HTML attribute, not the DOM property. After a user interacts with the checkbox, the attribute and property diverge. The checked property tracks the live state. The attribute only reflects the initial value from markup.

ApproachControlsTracks User Interaction
checkbox.checked = trueDOM propertyYes
checkbox.setAttribute('checked', '')HTML attributeNo
checkbox.removeAttribute('checked')HTML attributeNo

Always use the property for runtime behavior. The attribute is only relevant for the initial HTML render.

Form Validation with Checkboxes

A practical use case is requiring a terms-of-service checkbox before allowing form submission.

html
1<form id="signupForm">
2    <label>
3        <input type="checkbox" id="terms" />
4        I accept the terms and conditions
5    </label>
6    <button type="submit">Create account</button>
7</form>
javascript
1document.getElementById('signupForm').addEventListener('submit', event => {
2    const terms = document.getElementById('terms');
3    if (!terms.checked) {
4        event.preventDefault();
5        alert('Please accept the terms first.');
6    }
7});

This reads the live checked property at the moment that matters most: right before the form submits.

Dynamically Rendered Checkboxes

When checkboxes are rendered dynamically (through client-side templates, API responses, or framework rendering), be careful about stale references. If you cache the result of querySelectorAll and then new checkboxes are added to the DOM, those new elements will not be in the cached NodeList.

Two solutions exist.

Re-query inside the event handler.

javascript
1selectAll.addEventListener('change', () => {
2    const items = document.querySelectorAll('.row-item');
3    items.forEach(item => {
4        item.checked = selectAll.checked;
5    });
6});

Or use event delegation on a parent container.

javascript
1document.getElementById('tableBody').addEventListener('change', event => {
2    if (event.target.classList.contains('row-item')) {
3        const allItems = document.querySelectorAll('.row-item');
4        selectAll.checked = [...allItems].every(i => i.checked);
5    }
6});

Event delegation is generally the better approach for dynamic content because it scales without re-binding listeners.

Common Pitfalls

Using setAttribute instead of the checked property. The attribute and property diverge after user interaction. Always use checkbox.checked for runtime state.

Reading the checkbox before it exists in the DOM. If your script runs in the <head> without defer or DOMContentLoaded, the element has not been created yet and getElementById returns null.

Forgetting that programmatic changes do not fire events. Setting checkbox.checked = true does not trigger change listeners. Dispatch the event manually if downstream logic depends on it.

Caching querySelectorAll results for dynamic lists. The returned NodeList is static. New elements added after the query will not appear in it. Re-query or use event delegation.

Over-engineering with JavaScript when HTML does the job. A <label> element natively toggles its associated checkbox. The required attribute enforces presence during form submission without any JavaScript. Reach for JS only when you need behavior beyond what HTML provides.

Summary

  • Use checkbox.checked = true or false to check or uncheck a box.
  • Toggle with checkbox.checked = !checkbox.checked.
  • Listen for the change event to react to user interaction.
  • For groups, use querySelectorAll and iterate over the results.
  • Prefer the live checked property over HTML attribute manipulation.
  • Dispatch change events manually when toggling programmatically, if listeners depend on it.
  • Use event delegation for dynamically rendered checkbox lists.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.