Indeterminate state demo
by Arif Hasan
HTML
<ul>
<li><label><input type="checkbox" class="checkall" /> Check all</label>
<ul>
<li><label><input type="checkbox" class="child" /> Thing 1</label></li>
<li><label><input type="checkbox" class="child" /> Thing 2</label></li>
<li><label><input type="checkbox" class="child" /> Thing 3</label></li>
</ul>
</li>
<li><label><input type="checkbox" class="checkall" /> Check all</label>
<ul>
<li><label><input type="checkbox" class="child" /> Thing 1</label></li>
<li><label><input type="checkbox" class="child" /> Thing 2</label></li>
<li><label><input type="checkbox" class="child" /> Thing 3</label></li>
</ul>
</li>
<li><label><input type="checkbox" class="checkall" /> Check all</label>
<ul>
<li><label><input type="checkbox" class="child" /> Thing 1</label></li>
<li><label><input type="checkbox" class="child" /> Thing 2</label></li>
<li><label><input type="checkbox" class="child" /> Thing 3</label></li>
</ul>
</li>
</ul>
CSS
ul {
list-style: none;
}
label {
display:block
}
label:first-child {
font-weight:bold;
}
label:nth-child(n+2) {
margin-left:1em;
}
JavaScript
var children = $('.checkall').closest('li').find('.child');
// catch changes to child checkboxes and fire .change() on load
$('.child').change(function(){
// create var for parent .checkall
var checkall = $(this).closest('ul').parent().find('.checkall');
// do we have some checked? Some unchecked? Store as boolean varibles
var someChecked = $(this).closest('ul').find(":checkbox:checked").length > 0;
var someUnchecked = $(this).closest('ul').find(":checkbox:not(:checked)").length > 0;
// if we have some checked and unchecked, set checkall to indeterminate.
// If all are checked, set checkall to checked
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 checkboxes under it
$('.checkall').click(function() {
$(this).closest('li').find('.child').prop('checked', this.checked);
});