0

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);
            }
        });
    });
5
  • And what’s your actual problem with this? Commented Mar 17, 2014 at 10:28
  • If for example, a user checks on all the options under each country then for that country checkbox to be checked. If all country check boxes are checked, then the top Select All option should then be checked. Commented Mar 17, 2014 at 10:35
  • That is what you want. What your problem in implementing it is, you still haven’t told us. Commented Mar 17, 2014 at 10:37
  • I don't know where to start, my Javascript is quite poor! I believe I need to set a function on document.ready which mirrors my existing ones, but not sure of an elegant way to do this without duplicating code Commented Mar 17, 2014 at 10:43
  • If you don’t want to duplicate code, then use named functions that you can refer to in different places, instead of anonymous ones. Commented Mar 17, 2014 at 10:51

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I was after
0

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); }
}

1 Comment

Not quite - you'll see that with your example if you click on just one of the children under "Australia", i.e., VIC, then Australia will be checked. Australia should only be checked if BOTH NSW and VIC are checked

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.