Evonet
Evonet

Reputation: 3640

Setting checkbox values in Javascript based on nested values

As a follow up to this question Javascript for nested 'Select all' checkboxes, I have a list of checkboxes with a 'Select All' option for every item, and a 'Select All' item for each group.

I set the checkboxes server side, and what I'd like to do is use JQuery to set the 'select all' checkboxes if the child checkboxes are selected when the page loads, and also to set the select all checkboxes if the child options are checked.

<fieldset>
    <label>
        <input type="checkbox" class="checkall"><strong> All</strong>
    </label>
    <fieldset>
        <label>
            <input type="checkbox" name="checkedLocations" class="chkChild checkall" value="China" />
            <strong>&nbsp;&nbsp;China</strong>
        </label>
        <label>
            <input type="checkbox" name="checkedLocations" class="chkChild" value="Hong Kong" checked="checked" />
            &nbsp;&nbsp;&nbsp;Hong Kong
        </label>
    </fieldset>
    <fieldset>
        <label>
            <input type="checkbox" name="checkedLocations" class="chkChild checkall" value="Australia" />
            <strong>&nbsp;&nbsp;Australia</strong>
        </label>
        <label>
            <input type="checkbox" name="checkedLocations" class="chkChild" value="NSW" />
            &nbsp;&nbsp;&nbsp;NSW
        </label>

        <label>
            <input type="checkbox" name="checkedLocations" class="chkChild" value="VIC" />
            &nbsp;&nbsp;&nbsp;VIC
        </label>
    </fieldset>
</fieldset>

I have a Select All checkbox that selects/deselects everything, and a checkbox next to each country (Australia and China in this example) that selects/deselects all the locations in that country, with the following code:

    $(function () {
        $('.checkall').on('click', function () {
            $(this).closest('fieldset').find(':checkbox').prop('checked', this.checked);
        });
        $('.chkChild').on('click', function () {
            if (!$(this).is('.checkall')) {
                $(this).closest('fieldset').find('.checkall').prop('checked', false);
            }
        });
    });

Upvotes: 0

Views: 435

Answers (2)

Arun P Johny
Arun P Johny

Reputation: 388326

Try

$(function () {
    $('.checkall').on('change', function () {
        var $this = $(this);
        $this.closest('fieldset').find(':checkbox').prop('checked', this.checked);
        if($this.is('.chkChild')){
            $('.checkall:not(.chkChild)').prop('checked', $('.checkall.chkChild').not(':checked').length == 0)
        }
    });
    $('.chkChild:not(.checkall)').on('change', function () {
        var $fs = $(this).closest('fieldset'),
            $all = $fs.find('.checkall'),
            childstate = $fs.find('> label > input[type="checkbox"]').not('.checkall').not(':checked').length == 0;
        $all[childstate ? 'not' : 'filter'](':checked').prop('checked', childstate).change();
    });
});

Demo: Fiddle

Upvotes: 1

nettux
nettux

Reputation: 5406

If I'm correct about what you want then this should do it.

$(function () {
    checkBoxes();
    $('.checkall').on('click', function () {
        $(this).closest('fieldset').find(':checkbox').prop('checked', this.checked);
    });
    $('.chkChild').on('click', function () {
        if (!$(this).is('.checkall')) {
            $(this).closest('fieldset').find('.checkall').prop('checked', false);
        }
        checkBoxes();
    });
});

function checkBoxParents (jelem) {
    jelem.parents('fieldset')
    .find("> label > input[type=checkbox]:first")
    .prop('checked', jelem.prop('checked'));
}

function checkBoxes () {
    var any = false;
    $('.chkChild').each( function () {
        if ($(this).prop('checked')) {
            checkBoxParents($(this));
            any = true;
        }
    });
    if (!any) { $(".checkall").prop("checked", false); }
}

Upvotes: 0

Related Questions