<ul>
<li><input type="checkbox" name="item-1" />Item 1
<ul class="sublist">
<li><input type="checkbox" name="item-1-sublist" />Item 1-1</li>
<li><input type="checkbox" name="item-1-sublist" />Item 1-2</li>
<li><input type="checkbox" name="item-1-sublist" />Item 1-3</li>
</ul>
</li>
<li>
<input type="checkbox" name="item-2" />Item 2
<ul class="sublist">
<li><input type="checkbox" name="item-2-sublist" />Item 2-1</li>
<li><input type="checkbox" name="item-2-sublist" />Item 2-2</li>
<li><input type="checkbox" name="item-2-sublist" />Item 2-3</li>
</ul>
</li>
</ul>
Considering the code above, if the user clicks on one of the main-level checkboxes (ie, Item 1 or Item 2), how would I go about toggling all checkboxes in the neighboring list with the sublist
class value? I don't want to use any other class or id values because I'll have several types of sublists that need to be toggled independently; I don't want to duplicate chunks of code for each set of class/id values.
I've had the toggle-all-children-of neighbor but I've had to scrap that code.
You could use the $.parent() functions, like so (demo):
$('input[name="item-1"], input[name="item-2"]').change(function() {
var checkbox = $(this), checked = checkbox.is(':checked');
$('ul.sublist input[type="checkbox"]', checkbox.parent()).attr('checked', checked);
})
This code could be a little cleaner if your child check boxes had a name that didn't start with the same string as their parents like so:
<ul>
<li><input type="checkbox" name="item-1" />Item 1
<ul class="sublist">
<li><input type="checkbox" name="sublist-item-1-1" />Item 1-1</li>
<li><input type="checkbox" name="sublist-item-1-2" />Item 1-2</li>
<li><input type="checkbox" name="sublist-item-1-3" />Item 1-3</li>
</ul>
</li>
<li>
<input type="checkbox" name="item-2" />Item 2
<ul class="sublist">
<li><input type="checkbox" name="sublist-item-2-1" />Item 2-1</li>
<li><input type="checkbox" name="sublist-item-2-2" />Item 2-2</li>
<li><input type="checkbox" name="sublist-item-2-3" />Item 2-3</li>
</ul>
</li>
</ul>
and:
$('input[name^="item-"]').change(function() {
var checkbox = $(this), checked = checkbox.is(':checked');
$('ul.sublist input[type="checkbox"]', checkbox.parent()).attr('checked', checked);
})
This uses the pseudo selector ^=
which means starts with. You could use that in your original HTML because your child selectors all start with the name string.
------Edit------
For a better result use prop instead of attr, sometimes the attr works only the first time you change the values. So it would be:
$('input[name^="item-"]').change(function() {
var checkbox = $(this), checked = checkbox.is(':checked');
$('ul.sublist input[type="checkbox"]', checkbox.parent()).prop('checked', checked);
})