¿Por qué esta opción "Todo / ninguno" no hace su trabajo? No puedo ver por qué .attr('checked', status); no alterna todas las casillas de verificación.

¿Y cuál es la forma más inteligente de ocultar / mostrar elementos de #main que pertenecen a categorías seleccionadas?

$('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>
0
Basj 10 may. 2016 a las 01:05

5 respuestas

La mejor respuesta

Esto establece las casillas de verificación y la visibilidad div según sea necesario.

Utiliza opacity para simular una casilla de verificación atenuada.

$('[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>
1
Rick Hitchcock 9 may. 2016 a las 23:00

Todas las respuestas aquí fueron geniales. Solo para referencia futura, publico el que usaré (que es una mezcla de @ RickHitchcock y el uso de estado indeterminado de una casilla de verificación):

$('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>
1
Basj 9 may. 2016 a las 23:10
// 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>
1
Jose Hermosilla Rodrigo 9 may. 2016 a las 22:23

Como se mencionó aquí, debe utilizar jQuery's . prop () para marcar / desmarcar elementos de la casilla de verificación.

Así que intenta cambiar tu controlador de esta manera:

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

Para ocultar / mostrar elementos, recomiendo iterar sobre cada uno:

$('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();
  }
});

Con respecto a su última pregunta para colorear, recomendaría usar una clase, por ejemplo, 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');
}
2
Community 23 may. 2017 a las 10:28

Utilice .prop() no .attr()

Ver 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>
2
Jeff B 9 may. 2016 a las 22:11