0

Why doesn't this "All / none" option do his job? I can't see why .attr('checked', status); doesn't toggle all the checkboxes.

And what's the most clever way to hide / show elements of #main belonging to selected categories?

$('input[name="all"]').click(function() {
  var status = $(this).is(':checked');
  alert(status);
  $('input[type="checkbox"]').attr('checked', status);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
  <div class="cat1">Element of category1</div>
  <div class="cat4">Element of category4</div>
  <div class="cat3">Element of category3</div>
  <div class="cat1">Element of category1</div>
  <div class="cat2">Element of category2</div>
</div>

<label>
  <input type="checkbox" name="all" checked="true">
  All / none
</label>
<label>
  <input type="checkbox" name="cat1" checked="true">
  A
</label>
<label>
  <input type="checkbox" name="cat2">
  B
</label>
<label>
  <input type="checkbox" name="cat3">
  C
</label>
<label>
  <input type="checkbox" name="cat4">
  D
</label>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Basj
  • 41,386
  • 99
  • 383
  • 673

5 Answers5

2

Use .prop() not .attr()

See http://api.jquery.com/prop/

$('input[name="all"]').click(function(){ var status = $(this).is(':checked'); alert(status); $('input[type="checkbox"]').prop('checked', status); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label><input type="checkbox" name="all" checked="true">All / none</label>
<label><input type="checkbox" name="cat1" checked="true">A</label>
<label><input type="checkbox" name="cat2">B</label>
<label><input type="checkbox" name="cat3">C</label>
<label><input type="checkbox" name="cat4">D</label>
Jeff B
  • 29,943
  • 7
  • 61
  • 90
2

As mentioned here, you should make use of jQuery's .prop() function for checking/unchecking checkbox elements.

So try to change your handler like so:

$('input[name="all"]').click(function(){
    var status = !!$(this).prop('checked');
    alert(status);
    $('input[type="checkbox"]').prop('checked', status);
});

To hide/show elements, I recommend iterating over each one:

$('input[type="checkbox"]').each(function() {
  var name = $(this).attr('name');
  var status = !!$(this).prop('checked');
  if (status) {
    $('#main').find('.' + name).show();
  } else {
    $('#main').find('.' + name).hide();
  }
});

Regarding your last question for coloring, I'd recommend using a class, say for example gray.

var total = $('input[type="checkbox"]').not('[name=all]').length;
var count = $('input[type="checkbox"]:checked').not('[name=all]').length;
if (count === total) {
  $('input[name="all"]').removeClass('gray');
} else {
  $('input[name="all"]').addClass('gray');
}
Community
  • 1
  • 1
smaili
  • 1,245
  • 9
  • 18
  • Thanks! Do you have an idea for the show / hide part of the question? I'm thinking about it, but don't find a really clever way. – Basj May 09 '16 at 22:14
  • Thanks a lot! Last thing: how would you turn the "all/none" checkbox to grey, (i.e. not checked, not unchecked, i.e. something like `indeterminate = true;`) when not all checkboxes are checked or not all of them are unchecked? – Basj May 09 '16 at 22:23
  • You want the "all/none" checkbox gray when every checkbox is checked? – smaili May 09 '16 at 22:27
  • No I want it grey when some are checked, some are unchecked – Basj May 09 '16 at 22:29
  • Updated my answer. – smaili May 09 '16 at 22:36
1

// Bind also the single checkboxes to show/hide the elements in div
$('input[type = "checkbox"]').click(function(){
  if($(this).prop('checked'))
    $('div.' + $(this).attr('name')).show();
  else 
    $('div.' + $(this).attr('name')).hide();
});

$('input[name="all"]').click(function(){ 
  var status = $(this).is(':checked'); 
  alert(status);    
   $('input[type="checkbox"]').each(function(){
     $(this).prop('checked', status);
     if(!status)
       $('div.' + $(this).attr('name')).hide();
     else
       $('div.' + $(this).attr('name')).show();
 }); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div>
  <div class="cat1">Element of category1</div>
  <div class="cat4">Element of category4</div>
  <div class="cat3">Element of category3</div>
  <div class="cat1">Element of category1</div>
  <div class="cat2">Element of category2</div>
</div>

<label><input type="checkbox" name="all" checked="true">All / none</label>
<label><input type="checkbox" name="cat1" checked="true">A</label>
<label><input type="checkbox" name="cat2">B</label>
<label><input type="checkbox" name="cat3">C</label>
<label><input type="checkbox" name="cat4">D</label>
Jose Hermosilla Rodrigo
  • 3,513
  • 6
  • 22
  • 38
1

This sets the checkboxes and the div visibility as needed.

It uses opacity to simulate a grayed-out checkbox.

$('[name="all"]').click(function() {  //set all checkboxes to match All / none
  $(':checkbox')
    .prop('checked', this.checked)
    .change();
});

$('input')
  .change(function() {  //show divs corresponding to checked input
    var checked= $(':checkbox:not([name="all"]):checked').length;

    $('div.' + this.name)
      .toggle(this.checked);

    $('[name="all"]')
      .prop('checked', checked > 0)
      .toggleClass('someChecked', checked && checked<$(':checkbox:not([name="all"])').length);
  })
  .change();  //run the method immediately

$('[name="all"]').click(function() {  //set all checkboxes to match All / none
  $(':checkbox')
    .prop('checked', this.checked)
    .change();
});

$('input')
  .change(function() {  //show divs corresponding to checked input
    var checked= $(':checkbox:not([name="all"]):checked').length;
  
    $('div.' + this.name)
      .toggle(this.checked);

    $('[name="all"]')
      .prop('checked', checked > 0)
      .toggleClass('someChecked', checked && checked<$(':checkbox:not([name="all"])').length);
  })
  .change();  //run the method immediately
.someChecked {
  opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
  <div class="cat1">Element of category1</div>
  <div class="cat4">Element of category4</div>
  <div class="cat3">Element of category3</div>
  <div class="cat1">Element of category1</div>
  <div class="cat2">Element of category2</div>
</div>

<label>
  <input type="checkbox" name="all" checked="true">
  All / none
</label>
<label>
  <input type="checkbox" name="cat1" checked="true">
  A
</label>
<label>
  <input type="checkbox" name="cat2">
  B
</label>
<label>
  <input type="checkbox" name="cat3">
  C
</label>
<label>
  <input type="checkbox" name="cat4">
  D
</label>
Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
  • Thanks! A little something: how would you turn the "all/none" checkbox to grey, (i.e. semi-checked) when some checkboxes are checked and some are unchecked? – Basj May 09 '16 at 22:26
  • Styling checkboxes is rather tricky. See http://stackoverflow.com/questions/7398462/css-background-color-attribute-not-working-on-checkbox-inside-div – Rick Hitchcock May 09 '16 at 22:37
  • Actually, you could use `opacity` to simulate the style. Updated my answer. – Rick Hitchcock May 09 '16 at 22:44
1

All answers here were great. Just for future reference, I post the one I'll use (which is a mix of @RickHitchcock's and the usage of indeterminate state of a checkbox) :

$('input[name="all"]').click(function() { $(':checkbox').prop('checked', this.checked).change(); });
$('input[type="checkbox"]').change(function() {  
  var checked = $(':checkbox:not([name="all"]):checked').length;
  $('div.' + this.name).toggle(this.checked);
  $('input[name="all"]').prop('checked', checked > 0)
                    .prop('indeterminate', checked && checked < $(':checkbox:not([name="all"])').length);
}).change();  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
  <div class="cat1">Element of category1</div>
  <div class="cat4">Element of category4</div>
  <div class="cat3">Element of category3</div>
  <div class="cat1">Element of category1</div>
  <div class="cat2">Element of category2</div>
</div>
<label><input type="checkbox" name="all" checked>All / none</label>
<label><input type="checkbox" name="cat1" checked>A</label>
<label><input type="checkbox" name="cat2" checked>B</label>
<label><input type="checkbox" name="cat3" checked>C</label>
<label><input type="checkbox" name="cat4" checked>D</label>
Basj
  • 41,386
  • 99
  • 383
  • 673