Reputation: 115
I have to use group of checkboxes in my project.
This is how my HTML look like:
<table id="myTable">
<tr>
<td>
<label>
<input type="checkbox" class="parent" name="mod[6]" value="1">
</label>
</td>
<td><span>Parent Module</span></td>
<td>
<label>
<input type="checkbox" name="mod[7]" value="1"> Sub Module
</label>
<label>
<input type="checkbox" name="mod[8]" value="1"> Sub Module
</label>
<label>
<input type="checkbox" name="mod[9]" value="1"> Sub Module
</label>
</td>
</tr>
<tr>.....</tr>
<tr>.....</tr>
</table>
Using this checkboxes, users can select their preferred parent and sub module selection. When making that selection, it should work as follows.
I have done this work to some extent. But I look forward to your help in completing this.
This is how I tried it using Jquery.
$('#myTable').on( "change", "label > input[type=checkbox]", function(e) {
var checkboxes = $(this).closest('tr').find("input[type=checkbox]");
if ($(this).hasClass("parent")) {
if ($(this).prop("checked")) {
checkboxes.prop("checked", true);
}
}
});
Upvotes: 0
Views: 2819
Reputation: 44088
Added a "Check All" box in the <thead>
Added the third state called indeterminate
which is applied to a .parent
or #all
when some of their subordinate checkboxes are checked.
Assigned .child
class to the subordinate checkboxes just to make it a little easier to follow hopefully. Details are commented in the example.
// *️⃣ Code for indeterminate state - There are comments for removal
// Bind all checkboxes to the change event
$(':checkbox').on('change', checkUncheck);
function checkUncheck(e) {
// The tag the user checked/unchecked
const $this = $(this);
// Reference to the closest <tr>
const $row = $this.closest('tr');
/*
If the user clicked a .parent...
...and if it is checked...
... .find() all the <td> of $row...
...and check them all...
...otherwise uncheck them all
*/
if ($this.is('.parent')) {
if ($this.is(':checked')) {
$row.find('.child').prop('checked', true);
} else {
$row.find('.child').prop('checked', false);
}
}
/*
If the user checked/unchecked a .child...
... .makeArray() of all of $row .child and...
... if .every() <td> is .checked then check .parent
... and if .some() <td> are .checked then .parent is...
... indeterminate, otherwise uncheck .parent
*/
if ($this.is('.child')) {
$row.find('.parent').prop('indeterminate', false); //*️⃣
const chxArray = jQuery.makeArray($row.find('.child'));
let rowChecked = chxArray.every(cb => cb.checked); //*️⃣
let someChecked = chxArray.some(cb => cb.checked);
if (rowChecked) { /* if (someChecked) { */ //*️⃣
$row.find('.parent').prop('checked', true);
} else if (someChecked) {
$row.find('.parent').prop('indeterminate', true); //*️⃣
} else {
$row.find('.parent').prop('checked', false);
}
}
/*
If the user clicked #all...
...and if it is checked...
... .find() all the <td> of $tB...
...and check them all...
...otherwise uncheck them all
*/
if ($this.is('#all')) {
$('.parent').prop('indeterminate', false); //*️⃣
if ($this.is(':checked')) {
$(':checkbox').prop('checked', true);
} else {
$(':checkbox').prop('checked', false);
}
}
/*
If the user checked/unchecked a .child or .parent...
... .makeArray() of all of <td> in <tbody> and...
... if .every() <td> is checked...
... #all is checked and if .some() <td> are checked...
... then #all is indeterminate...
... otherwise uncheck #all
*/
let allArray = jQuery.makeArray($(':checkbox').not('#all'));
if (allArray.every(cb => cb.checked)) {
$('#all').prop('indeterminate', false); //*️⃣
$('#all').prop('checked', true); /* Move to: ✳️ */
} else if (allArray.some(cb => cb.checked)) {
$('#all').prop('indeterminate', true); //*️⃣ ✳️
} else {
$('#all').prop('indeterminate', false); //*️⃣
$('#all').prop('checked', false);
}
}
<table><thead><tr><th><label><input type=checkbox id=all></label><th>All Modules<th><tbody><tr><td><label><input type=checkbox class=parent name=mod[6] value=1></label><td><span>Parent Module</span><td><label><input type=checkbox class=child name=mod[7] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[8] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[9] value=1> Sub Module</label><tr><td><label><input type=checkbox class=parent name=mod[6] value=1></label><td><span>Parent Module</span><td><label><input type=checkbox class=child name=mod[7] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[8] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[9] value=1> Sub Module</label><tr><td><label><input type=checkbox class=parent name=mod[6] value=1></label><td><span>Parent Module</span><td><label><input type=checkbox class=child name=mod[7] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[8] value=1> Sub Module</label> <label><input type=checkbox class=child name=mod[9] value=1> Sub Module</label></table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 2
Reputation: 764
here is a working demo. you need to update the code with else condition where you uncheck parents' checkbox on uncheck child.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#myTable').on( "change", "label > input[type=checkbox]", function(e) {
var checkboxes = $(this).closest('tr').find("input[type=checkbox]");
if ($(this).hasClass("parent")) {
if ($(this).prop("checked")) {
checkboxes.prop("checked", true);
}else
{
checkboxes.prop("checked", false);
}
}else if($(this).hasClass("child")){
if ($(this).prop("checked")) {
$(".parent").prop("checked",true)
}else
{
$(".parent").prop("checked",false)
}
}
});
});
</script>
</head>
<body>
<table id="myTable">
<tr>
<td>
<label>
<input type="checkbox" class="parent" name="mod[6]" value="1">
</label>
</td>
<td><span>Parent Module</span></td>
<td>
<label>
<input class="child" type="checkbox" name="mod[7]" value="1"> Sub Module
</label>
<label>
<input class="child" type="checkbox" name="mod[8]" value="1"> Sub Module
</label>
<label>
<input class="child" type="checkbox" name="mod[9]" value="1"> Sub Module
</label>
</td>
</tr>
<tr>.....</tr>
<tr>.....</tr>
</table>
</body>
</html>
Upvotes: 0