loading...

Marcar y desmarcar checkbox de manera simultánea con jQuery

juananruiz profile image Juanan Ruiz Originally published at galatar.com on ・2 min read

Hace unos días tuve que hacer un formulario para enviar un correo a una lista cerrada de personas, pero me pedían la posibilidad de enviar el correo a todos o a una parte de la lista cerrada.

Algo parecido a lo que se muestra en la siguiente imagen

Formulario con checks multiples

Tenía hecho algo similar en un proyecto más antiguo y me decidí por la técnica del corta/pega pero para mi sorpresa el script funcionaba la primera vez y luego se negaba a repetir la hazaña.

Os pongo el fragmento de HTML de ejemplo y el script inicial para comentaros el problema.

<table border="1">
  <tr>
    <th><input type="checkbox" id="selectall"></th>
    <th>Participantes</th>
  </tr>
  <tr>
    <td><input type="checkbox" class="case" name="case[]" value="1"></td>
    <td>Fulano de Tal y Cual</td>
  </tr>
  <tr>
    <td><input type="checkbox" class="case" name="case[]" value="2"></td>
    <td>Irene Sal de la Cueva</td>
  </tr>
  <tr>
    <td><input type="checkbox" class="case" name="case[]" value="3"></td>
    <td>Zutano Ruiz Ruiz</td>
  </tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
  $("#selectall").on("click", function() {
    $(".case").attr("checked", this.checked);
  });
</script>

Como ves he definido un primer checkbox con el identificador "selectall" para seleccionar o deseleccionar al resto que he marcado con la clase "case" para poder referirme a ellos en conjunto.

Cuando se hace "click" en el checkbox superior todos los demás cambian su estado. El fallo de este código, que yo juraría que funcionaba en versiones antiguas de jQuery, es que la función "attr" sólo modifica el atributo original del elemento, cuando la página se carga, pero no una vez que se ha modificado. Para que funcione en cualquier circunstancia hay que usar la función "prop".

$("#selectall").on("click", function() {  
  $(".case").prop("checked", this.checked);  
});

Puestos a mejorar un poco más el script he agregado otro evento para que cuando se desmarquen uno o más elementos se desmarque también el checkbox superior. Y si todos están marcados pues que se marque el superior también.

$("#selectall").on("click", function() {  
  $(".case").prop("checked", this.checked);  
});  

// if all checkbox are selected, check the selectall checkbox and viceversa  
$(".case").on("click", function() {  
  if ($(".case").length == $(".case:checked").length) {  
    $("#selectall").prop("checked", true);  
  } else {  
    $("#selectall").prop("checked", false);  
  }  
});

Espero que os sea de utilidad en algún momento. En cualquier caso os dejo el código en codepen para que podáis jugar con él.

Discussion

pic
Editor guide