Home > Blockchain >  javascript check all and uncheck all checkbox
javascript check all and uncheck all checkbox

Time:12-11

I have select all check box with some option when i click select all i select all the option and when i remove the select all i remove it from all option and the code below work for that.

What i try to do is when i unselect one of the option the select all box should be unselected and if i select all the option without selecting the select all option the check all box should be selected.

How can i do that?

let checkboxes = document.querySelectorAll("input[type = 'checkbox']");

function checkAll(myCheckBox) {
  if (myCheckBox.checked == true) {
    checkboxes.forEach(function(checkbox) {
      checkbox.checked = true;
    });
  } else {
    checkboxes.forEach(function(checkbox) {
      checkbox.checked = false;
    });
  }
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: grid;
  place-content: center;
}

input[type="checkbox"] {
  margin-bottom: 10px;
  cursor: pointer;
}

input[type="checkbox"]:not(:first-child) {
  margin-left: 20px;
}
<div >
  <input type="checkbox" id="check-all" onchange="checkAll(this)">
  <label for="check-all">Select All</label>
  <br/>
  <input type="checkbox" id="option-a">
  <label for="option-a">Option A</label>
  <br/>
  <input type="checkbox" id="option-b">
  <label for="option-b">Option B</label>
  <br/>
  <input type="checkbox" id="option-c">
  <label for="option-c">Option C</label>
  <br/>
</div>

CodePudding user response:

You can add a change event listener to all of those checkboxes (except for the automatic select all checkbox).

So in this demo I used a disciminant being the class auto that only the "select all" checkbox has.

Then I select all elements being input but not having the class auto.

And for each of those I add an event listener for the change event that will uncheck the "select all" checkbox if any of those was unchecked and that will check the "select all" checkbox if otherwise all of them are checked.

let checkboxes = document.querySelectorAll("input[type='checkbox']");
let cbActual = document.querySelectorAll('input[type=checkbox]:not([class=auto])');

cbActual.forEach(
  cb => {
    cb.addEventListener('change', (event)=>{
      if(!event.target.checked)
        document.getElementById('check-all')
          .checked = false;
      else{
        if( [...cbActual].every(cb => cb.checked === true) )
           document.getElementById('check-all')
            .checked = true;
      }
    });
  }
);

function checkAll(myCheckBox) {
  if (myCheckBox.checked == true) {
    checkboxes.forEach(function(checkbox) {
      checkbox.checked = true;
    });
  } else {
    checkboxes.forEach(function(checkbox) {
      checkbox.checked = false;
    });
  }
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: grid;
  place-content: center;
}

input[type="checkbox"] {
  margin-bottom: 10px;
  cursor: pointer;
}

input[type="checkbox"]:not(:first-child) {
  margin-left: 20px;
}
<div >
  <input type="checkbox" id="check-all" onchange="checkAll(this)" >
  <label for="check-all">Select All</label>
  <br/>
  <input type="checkbox" id="option-a">
  <label for="option-a">Option A</label>
  <br/>
  <input type="checkbox" id="option-b">
  <label for="option-b">Option B</label>
  <br/>
  <input type="checkbox" id="option-c">
  <label for="option-c">Option C</label>
  <br/>
</div>

CodePudding user response:

To accomplish what you want to do, you can use a boolean variable to store the state of the "Select All" checkbox. In the click event handler for the "Select All" checkbox, you can change the value of the variable and then use that value to determine whether to select or deselect all of the other options.

You can also add an event handler for each of the other options in the list, and use that handler to uncheck the "Select All" checkbox when one of the options is unchecked.

// Declare a variable to store the state of the "Select All" checkbox
let selectAllChecked = false;

// Add a click event handler for the "Select All" checkbox
document.getElementById('select-all-checkbox').addEventListener('click', function() {
  // Update the state of the "Select All" checkbox
  selectAllChecked = !selectAllChecked;

  // Get a list of all the other checkboxes
  const checkboxes = document.querySelectorAll('input[type="checkbox"]');

  // Loop through the checkboxes and set their checked property
  // based on the state of the "Select All" checkbox
  checkboxes.forEach(function(checkbox) {
    checkbox.checked = selectAllChecked;
  });
});

// Add a click event handler for each of the other checkboxes
document.querySelectorAll('input[type="checkbox"]').forEach(function(checkbox) {
  checkbox.addEventListener('click', function() {
    // If any of the other checkboxes are not checked,
    // set the state of the "Select All" checkbox to false
    if (!checkbox.checked) {
      selectAllChecked = false;
      document.getElementById('select-all-checkbox').checked = false;
    }
  });
});

CodePudding user response:

When checkall is clicked either all or none are selected. When one of the options are checked/unchecked the status of checkall is decided based on the filter function.

I changed the markup of the form a bit. You can "group" check boxes on their name. And try avoiding IDs in a form -- in general it is better to use the name attribute.

document.addEventListener('DOMContentLoaded', e => {
  document.forms.form01.addEventListener('change', result_change);
});

function result_change(e) {
  let form = e.target.form;
  /* e.target.form.option could either be a NodeList or just one Element.
  A iterable is needed. */
  let options = (form.option.length) ? form.option : [form.option];
  switch (e.target.name) {
    case 'checkall':
      let checked = e.target.checked;
      [...options].forEach(option => option.checked = checked);
      break;
    case 'option':
      let allchecked = ([...options].filter(option => !option.checked).length == 0) ? ? true;
      form.checkall.checked = allchecked ? true : false;
      break;
  }
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: grid;
  place-content: center;
}

input[type="checkbox"] {
  margin-bottom: 10px;
  cursor: pointer;
}

input[type="checkbox"]:not(:first-child) {
  margin-left: 20px;
}
<form name="form01">
  <input type="checkbox" name="checkall">
  <label for="check-all">Select All</label>
  <br/>
  <input type="checkbox" name="option" value="a">
  <label for="option-a">Option A</label>
  <br/>
  <input type="checkbox" name="option" value="b">
  <label for="option-b">Option B</label>
  <br/>
  <input type="checkbox" name="option" value="c">
  <label for="option-c">Option C</label>
  <br/>
</form>

CodePudding user response:

Prefer to use event propagation to handle the change events of all checkboxes in one listener.

To make use of event propagation, you have to be able to distinguish them from the "Select all" checkbox. To distinuish them, you can:

  • Use a class (on either the "Select all" or all other checkboxes).
  • Group the checkboxes (except the "Select all" checkbox) in an element.
  • Check if the changing checkbox is the first (i.e. the "Select all") checkbox.
  • ...

I chose to use a grouping element so that the "Select all" checkbox is not included:

const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
// NodeList has .forEach() but not .every(). Transform to an array, which has both.
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));

cbAll.addEventListener("change", () => {
  // If cbAll.checked changes, cbAll.checked should override all other checkboxes' checked.
  checkboxes.forEach(cb => cb.checked = cbAll.checked);
});

// This listener will be called if *any* checkbox (in cbGroup) changes.
// Update cbAll.checked to true if all checkboxes are checked; otherwise false.
cbGroup.addEventListener("change", () => {
  const areAllChecked = checkboxes.every(cb => cb.checked);
  cbAll.checked = areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
  <label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
  <label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
  <label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>

Alternatively you can add listeners to all checkboxes individually.


Checkboxes can also be in a "third" state: Indeterminate. Note: This is not a true state, as checkboxes can only be either checked or unchecked. An indeterminate checkbox hides its checkedness under the pretence of being indeterminate.

This is most commonly used for checkboxes like this "Select all" checkbox; where a checkbox describes the state of a group of checkboxes.

The above example can be modified to make use of it:

const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));

cbAll.addEventListener("change", () => {
  checkboxes.forEach(cb => cb.checked = cbAll.checked);
});

cbGroup.addEventListener("change", () => {
  const amountChecked = checkboxes.reduce((amount, cb) => {
    // Number(bool) returns 1 if bool === true; otherwise 0.
    return amount   Number(cb.checked);
  }, 0);

  const areAllChecked = amountChecked === checkboxes.length;
  const areSomeChecked = amountChecked > 0;

  cbAll.checked = areAllChecked;
  cbAll.indeterminate = areSomeChecked && !areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
  <label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
  <label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
  <label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>

  • Related