user12109321358
user12109321358

Reputation: 461

Check All checkbox should be unchecked

    function toggle(source) {
      checkboxes = document.getElementsByName('options[]');
      for (var i = 0, n = checkboxes.length; i < n; i++) {
        checkboxes[i].checked = source.checked;
      }
    }
<form class="unsubscribe_form" action="process.php" method="post">
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
  <label for="checkbox-1-1"></label>Option 1
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
  <label for="checkbox-1-2"></label>Option 2
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
  <label for="checkbox-1-3"></label>Option 3
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
  <label for="checkbox-1-4"></label>Option 4
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
  <label for="checkbox-1-5"></label>Option 5
  <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" onClick="toggle(this)" />
  <label for="checkbox-1-6"></label>All
  <br>
  <input type="submit" name="formSubmit" value="Unsubscribe" />
</form>

When I check the All checkbox, of course, it will mark all the checkboxes, but once I uncheck one checkbox, the All checkbox is still checked. This should be unchecked. How should I do that using JS?

Upvotes: 1

Views: 929

Answers (2)

David Thomas
David Thomas

Reputation: 253318

I'd suggest the following:

function toggle() {
  // getting a reference to all the 'name="option[]" elements:
  var options = document.getElementsByName('options[]'),
    // a reference to the 'all' checkbox:
    all = document.getElementById('checkbox-1-6');

  // if the changed checkbox is the 'all':
  if (this === all) {
    // we iterate over all the options checkboxes (using
    // Array.prototype.forEach()):
    Array.prototype.forEach.call(options, function(checkbox) {
      // and we set their checked property to the checked property
      // state of the 'all' checkbox:
      checkbox.checked = all.checked;
    });
  } else {
    // otherwise we set the 'all' checkbox to the state of
    // the Boolean returned by Array.prototype.every(),
    // which returns true if all checkboxes evaluate to
    // the condition within the function, otherwise false:
    all.checked = Array.prototype.every.call(options, function(checkbox) {
      return checkbox.checked;
    });
  }
}

// getting a NodeList of all the elements of 'class="unsubscribe-checkbox"':
var options = document.querySelectorAll('.unsubscribe-checkbox');

// iterating over them, again with Array.prototype.forEach()
// and assigning a change event-listener, which will execute the
// name function:
Array.prototype.forEach.call(options, function(opt) {
  opt.addEventListener('change', toggle);
});

function toggle() {
  var options = document.getElementsByName('options[]'),
    all = document.getElementById('checkbox-1-6');
  if (this === all) {
    Array.prototype.forEach.call(options, function(checkbox) {
      checkbox.checked = all.checked;
    });
  } else {
    all.checked = Array.prototype.every.call(options, function(checkbox) {
      return checkbox.checked;
    });
  }
}

var options = document.querySelectorAll('.unsubscribe-checkbox');

Array.prototype.forEach.call(options, function(opt) {
  opt.addEventListener('change', toggle);
});
<form class="unsubscribe_form" action="process.php" method="post">
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
  <label for="checkbox-1-1"></label>Option 1
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
  <label for="checkbox-1-2"></label>Option 2
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
  <label for="checkbox-1-3"></label>Option 3
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
  <label for="checkbox-1-4"></label>Option 4
  <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
  <label for="checkbox-1-5"></label>Option 5
  <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" />
  <label for="checkbox-1-6"></label>All
  <br>
  <input type="submit" name="formSubmit" value="Unsubscribe" />
</form>

You may notice that I've removed the onClick attribute from the 'all' checkbox, in preference of unobtrusive JavaScript, where the event-handlers are assigned via the JavaScript itself (which ordinarily makes for more easily-maintained code, as the arguments to be passed to a given function are assigned in the code itself, rather than having to be separately updated in the HTML).

References:

Upvotes: 0

dfsq
dfsq

Reputation: 193261

You will need to add onchange event handlers to every checkbox and check inside if the "All" checkbox should be checked (all checkboxes are selected) or unchecked (at least one is deselected). For example like this:

var checkboxes =  [].slice.call(document.getElementsByName('options[]')),
    allCheckbox = document.querySelector('input[value="All"]');

checkboxes.forEach(function(checkbox) {
    checkbox.onchange = function() {
        if (!this.checked) {
            allCheckbox.checked = false;
        }
        else {
            var checked = checkboxes.filter(function(check) {
                return check.checked;
            });
            if (checked.length === checkboxes.length) {
                allCheckbox.checked = true;
            }
        }
    };
});

function toggle(source) {
    for (var i = 0, n = checkboxes.length; i < n; i++) {
        checkboxes[i].checked = source.checked;
    }
}
<form class="unsubscribe_form" action="process.php" method="post">
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-1" value="Option1">
    <label for="checkbox-1-1"></label>Option 1
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-2" value="Option2">
    <label for="checkbox-1-2"></label>Option 2
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-3" value="Option2">
    <label for="checkbox-1-3"></label>Option 3
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-4" value="Option3">
    <label for="checkbox-1-4"></label>Option 4
    <input type="checkbox" class="unsubscribe-checkbox" name="options[]" id="checkbox-1-5" value="Option3">
    <label for="checkbox-1-5"></label>Option 5
    <input type="checkbox" class="unsubscribe-checkbox" id="checkbox-1-6" value="All" onClick="toggle(this)" />
    <label for="checkbox-1-6"></label>All
</form>

Note that I converted checkboxes collection to array with [].slice.call in order to use convenient array methods. Simple for loops can be used instead.

Upvotes: 0

Related Questions