简体   繁体   中英

Fixing toggle all behavior in checkbox element

I'm trying to toggle all checkboxes on a table and my code works but has a few issues and I don't find how to get ride of them. So here is the code:

$(function () {
    $('#toggleCheckbox').on('click', function () {
        var $toggle = $(this).is(':checked');
        $("#codigoArancelarioBody").find("input:checkbox").click();
    });
});

Take a look at this Fiddle I setup for testing and do this tests:

  • Mark the first checkbox (the one at table heading level) the rest of them inside #codigoArancelarioBody get checked and this is right
  • Mark first the checkbox at the first row (the only at table body level) and then mark the toggleAll you will see how things goes wrong since if I check the toggleAll them all should remain checked and that's the wrong part on my code

How I can fix this? Also I'll like to add a class 'removedAlert' to those TR I mark, how?

You need two click event handlers, one for the check/uncheck all box and one for the other ones

JS

$('#toggleCheckbox').on('click', function () {
    var $toggle = $(this).is(':checked');
    $("#codigoArancelarioBody").find("input:checkbox").prop("checked", $toggle);
});

$("#codigoArancelarioBody input:checkbox").on('click', function () {
    if (!$(this).is(':checked')) {
        $('#toggleCheckbox').prop("checked", false);
    } else if ($("#codigoArancelarioBody input:checkbox").length == $("#codigoArancelarioBody input:checkbox:checked").length) {
        $('#toggleCheckbox').prop("checked", true);
    }
});

DEMO


since the same code will be applied in a lot of places on my code and to avoid DRY, I'll like to pass the selector as a parameter in all your code solution could you edit your post to achieve this?

$toggleCheckBox = $('#toggleCheckbox');
$checkBoxTbody = $("#codigoArancelarioBody");

$toggleCheckBox.on('click', function () {
    var $toggle = $(this).is(':checked');
    $checkBoxTbody.find("input:checkbox").prop("checked", $toggle);
});

$checkBoxTbody.find("input:checkbox").on('click', function () {
    if (!$(this).is(':checked')) {
        $toggleCheckBox.prop("checked", false);
    } else if ($checkBoxTbody.find("input:checkbox").length == $checkBoxTbody.find("input:checkbox:checked").length) {
        $toggleCheckBox.prop("checked", true);
    }
});

DEMO

If you don't need the "click" event for something else you can do this:

$(function () {
    $('#toggleCheckbox').on('change', function () {
        var toggle = $(this).is(':checked');
        $("#codigoArancelarioBody").find("input:checkbox").prop('checked', toggle ).closest('tr').addClass('removedAlert');
    });
});

The code is actually executing what you told it to do, ie every time I click the checkbox on top click to other checkboxes. This way if a box is checked it will uncheck itself, because it won't mind if the top is checked or not.

What you really want is "when I check the box on top, check all the others, when I uncheck it, then uncheck all the others", which is sort of different as you see.

Try this:

 $(function () {
     // best practice: always store the selectors you access multiple times
     var checkboxes = $("#codigoArancelarioBody").find("input:checkbox"),
         toggleAll = $('#toggleCheckbox');

      toggleAll.on('click', function () {
         // is the top checkbox checked? return true, is it unchecked? Then return false.
        var $toggle = $(this).is(':checked');
        // .prop('checked', true) makes it checked, .prop('checked', false) makes it unchecked
        checkboxes.prop('checked', $toggle);
    });
 });

see: http://jsfiddle.net/gleezer/nnfg80x1/3/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM