Select All Checkbox with intermediate state

by Arif Hasan

HTML

<ul>
    <li><label><input type="checkbox" class="selectall" data-group="1" /> Select all</label>
        <ul>
            <li><label><input type="checkbox" class="child" data-group="1" /> Child 1</label></li>
            <li><label><input type="checkbox" class="child" data-group="1" /> Child 2</label></li>
            <li><label><input type="checkbox" class="child" data-group="1" /> Child 3</label></li>
        </ul>
    </li>
</ul>

JavaScript

(function($){
        $('.child').change(function(){
        // create var for parent .checkall and group
        var group = $(this).data('group'),
            checkall = $('.selectall[data-group="'+group+'"]');
    
        // do we have some checked? Some unchecked? Store as boolean variables
        var someChecked = $('.child[data-group="'+group+'"]:checkbox:checked').length > 0;
        var someUnchecked = $('.child[data-group="'+group+'"]:checkbox:not(:checked)').length > 0;
    
        // if we have some checked and unchecked, set .checkall, of the correct group, to indeterminate. 
        // If all are checked, set .checkall to checked
        checkall.prop("indeterminate", someChecked && someUnchecked);
        checkall.prop("checked", someChecked || !someUnchecked);
               
    // fire change() when this loads to ensure states are updated on page load
    }).change();
    
    // clicking .checkall will check all children in the same group.
    $('.selectall').click(function() {
        var group = $(this).data('group');
        $('.child[data-group="'+group+'"]').prop('checked', this.checked).change(); 
    });
}(window.jQuery));