Nested "Select All" checkboxes So after answering a question about nested linked checkboxes I mentioned it at work and surprisingly it turned out to be similar to something we needed.

The requirements were:


a "Select all" checkbox 
a nested "Select all" checkbox (only selects a small portion) 
Cannot rely upon the hierarchy of the markup. The given fiddle is an example only. EDIT:- from Discussions with John I now see there was this requirement and so I've added it. 


So realising it was different to the aforementioned question I set about writing my own.  I aimed for readability and minimal markup.

(function($) {
    $('input[type=checkbox][data-children]').unbind("change childchange childchangebubble").each(function() {
        var parent = $(this);

        var linkedChildren = $(parent.data("children"));

        //trigger a "childChange" event on the parent when any child is triggered.
        linkedChildren.bind("change childchangebubble", function() {
            parent.trigger("childchange");
        });

        parent.bind({
            "change": function(event) { // Bind change event to check all children
                linkedChildren.prop("checked", parent.prop("checked")).trigger("change");
            },
            "childchange": function() { // have to bind custom event seperately, there seems to be a jQuery bug.
                // When a child is changed recalculate if parent should be checked
                var noChildrenUnchecked = !linkedChildren.is(":not(:checked)");
                parent.prop("checked", noChildrenUnchecked).trigger("childchangebubble");
            }
        });
    });
})(jQuery);


the data-children attributes that are rendered to the page look like: data-children="#child2sub1, #child2sub2" on the parent and nothing extra needed on the children.

I'd love any feedback on readability/maintainability, performance etc.

current jsFiddle.
I have a suggestion.  Basically I'm not sure why you are adding so much to the HTML to handle the the parent and child checkboxes.  Isn't the hierarchy of the HTML enough to go on?  From the HTML you can already determine the parent and child relationships.  In additon why trigger more events.  Just handle the event as it bubbles up though the DOM.  

Below is an example of some code that I believe to be far more reusable and much easier to implement.  In addition, I have modified this to work with future checkboxes added to the DOM.  It may be necessary to load some of the children via AJAX and/or appending to the DOM therefore your method would require you to bind your function on each append to the DOM, where as mine would handle it though delegation of events.

$.fn.nestedCheckboxes = function (stopPropogation) {
    this.addClass('nestedCheckboxes');
    this.click(nestedCheckboxHandler);
    this.delegate(':has( &gt; input:checkbox)', 'click', nestedCheckboxHandler);
    function nestedCheckboxHandler (evt) {
        if ($(evt.target).is("input:checkbox")) {
            var parentContainer = $(this);
            var checkbox = parentContainer
                            .find(' &gt; input:checkbox:eq(0)');
            var parentCheckbox = parentContainer
                                    .parent()
                                    .closest(':has( &gt; input:checkbox)')
                                    .children('input:checkbox');

            if (evt.target == checkbox[0]) {
                $('input:checkbox', parentContainer)
                    .prop("checked", checkbox.prop("checked"));
            }
            var parentCheckboxValue = !parentCheckbox
                                        .parent()
                                        .find("input:checkbox")
                                        .not(parentCheckbox[0])
                                        .is("input:checkbox:not(:checked)");

            parentCheckbox.prop("checked",parentCheckboxValue);
        } else if (stopPropogation) {
            evt.stopPropagation();
        }
    };
};

$(function () {
    $('div').nestedCheckboxes();  //this is how you would use the function

    $('#addChildren').click(function () {
       $(this).after('&lt;ul&gt;&lt;li&gt;&lt;input type="checkbox" /&gt;&lt;label&gt;Child 2 SubChild 1&lt;/label&gt;&lt;/li&gt;&lt;li&gt;&lt;input type="checkbox" /&gt;&lt;label&gt;Child 2 SubChild2&lt;/label&gt;&lt;/li&gt;&lt;/ul&gt;');
       return false;
    });    

});


In addition I have added an option for the nestedCheckboxes to stopPropogation if an element other than a checkbox is clicked.  By default this if set to false.

Finally have a look at the fiddle I created and play around.  You will see that the HTML Markup is far more simplistic.

http://jsfiddle.net/jfhartsock/WwtJr/