3
votes

JQuery 1.9.1 and using IE8 and Firefox as browsers.

I had posted a question here that hadn't been answered - hoping that by re-formulating the question I may get an answer.

Below is the HTML for a couple rows in a table I am displaying on a web page.

<tr>
    <td>
        <label for="RoomNbr2" align="right">&nbsp;&nbsp;Room No 2
            <input type="checkbox" align="left" class="checkall" id="RoomNbr2" name="RoomNbr2">
        </label>
    </td>
    <td>
        <label for="PCNbr203" align="right">&nbsp;&nbsp;203
            <input type="checkbox" align="left" id="PCNbr203" name="PCNbr203" class="RoomNbr2">
        </label>
    </td>
    <td>
        <label for="PCNbr204" align="right">&nbsp;&nbsp;204
            <input type="checkbox" align="left" id="PCNbr204" name="PCNbr204" class="RoomNbr2">
        </label>
    </td>
</tr>
<tr>
    <td>
        <label for="RoomNbr3" align="right">&nbsp;&nbsp;Room No 3
            <input type="checkbox" align="left" class="checkall" id="RoomNbr3" name="RoomNbr3">
        </label>
    </td>
    <td>
        <label for="PCNbr310" align="right">&nbsp;&nbsp;310
            <input type="checkbox" align="left" id="PCNbr310" name="PCNbr310" class="RoomNbr3">
        </label>
    </td>
    <td>
        <label for="PCNbr320" align="right">&nbsp;&nbsp;320
            <input type="checkbox" align="left" id="PCNbr320" name="PCNbr320" class="RoomNbr3">
        </label>
    </td>
    <td>
        <label for="PCNbr340" align="right">&nbsp;&nbsp;340
            <input type="checkbox" align="left" id="PCNbr340" name="PCNbr340" class="RoomNbr3">
        </label>
    </td>
    <td>
        <label for="PCNbr350" align="right">&nbsp;&nbsp;350
            <input type="checkbox" align="left" id="PCNbr350" name="PCNbr350" class="RoomNbr3">
        </label>
    </td>
</tr>

If the user clicks on Room No 2 then all the PC's in Room No 2 (the RoomNbr2 class assigned to the individual PC's) get checked. Likewise, if Room No 2 is checked & then gets unchecked, all PCs with that class would follow suit.

I use this code to monitor the checkall class for the Rooms:

$('#mytable').on('click','.checkall', function() {
   $('input.' + this.id).prop('checked', this.checked);
   });

I use this code to monitor individual clicks on the table:

$('#mytable').on('click', function() {
   $('input.' + this.id).prop('checked', this.checked);
    });

What I need to do is to change the status of the Room No 2 (or 3) checkbox when it has been checked and one of the dependent checkboxes becomes unchecked.

For example:

If I click Room No 2, the checkbox for Room No 2 becomes checked, as will 203 & 204.

If I uncheck 203, then 204 should remain checked, with the checkbox for Room No 2 going to a status that is either unchecked (without altering the status for the checkbox for 204 ) or goes to an indeterminate status (something other than visually showing checked).

At any given time, I know which Machines have been checked:

$("input[name*=PC]:checked").map(function () {return this.name;}).get().join(",")

which is what I really want to know. I just do not want the Room No checkboxes to indicate they are checked when all dependent checkboxes are no longer checked. All the examples I find are of an all-checked/all-unchecked nature.

Would appreciate any thoughts or direction as to how best to resolve this issue.

3

3 Answers

1
votes

How about setting the checkboxes to indeterminate if they aren't all checked?

$(".checkall").prop("indeterminate", true);

A nice writeup on the subject: http://css-tricks.com/indeterminate-checkboxes/

1
votes

How about checking the number of checkboxes against the checked number of checkboxes and setting the main checkbox per line to checked, unchecked, or indeterminate?

jsFiddle example

$('#mytable').on('click', '.checkall', function () {
    $('input.' + this.id).prop('checked', this.checked);
});
$('#mytable').on('click', 'input:not(.checkall)', function () {
    var total = $(this).closest('tr').find('input:not(.checkall)').length;
    var checked = $(this).closest('tr').find('input:not(.checkall):checked').length;
    if (total == checked) {
        $(this).closest('tr').find('input:first').prop('checked', true);
        $(this).closest('tr').find('input:first').prop('indeterminate', false);
    } else if (checked == 0) {
        $(this).closest('tr').find('input:first').prop('checked', false);
        $(this).closest('tr').find('input:first').prop('indeterminate', false);
    } else {
        $(this).closest('tr').find('input:first').prop('indeterminate', true);
    }
});
0
votes

What about this strategy?

$('input[type=checkbox]').on('click', function() {
    var clickedCb = $(this);
    var tr = $(this).closest('tr');
    var mainCb = tr.children('td input')[0]; 
    if (clickedCb == mainCb) { // probably this check is not 100% correct.
        // do the checkall stuff
    } else {
        mainCb.prop('indeterminate', true);
    }
}