1
votes

I have a table which has a header row containing a checkbox and also has checkboxes in each of the body rows.

When the user checks the header checkbox, each of the body checkboxes also gets checked, and if one of these body checkboxes is unchecked the header checkbox gets unchecked. This is working fine, but I now want to add more tables which are linked to each of the body rows on the first table.

Here's an example of the html:

<table class="parent-table">
    <thead>
        <tr>
            <th>Title</th>
            <th>
                <input type="checkbox" />
            </th>
        </tr>
    </thead>
    <tbody>
        <tr data-user-id="ID1">
            <td>ID1</td>
            <td>
                <input type="checkbox" />
            </td>
        </tr>

    </tbody>
</table>

<br /><br />

<table class="child-table" id="ID1">
    <thead>
        <tr>
            <th>ID1</th>
            <th>
                <input type="checkbox" />
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>One</td>
            <td>
                <input type="checkbox" />
            </td>
        </tr>
        <tr>
            <td>Two</td>
            <td>
                <input type="checkbox" />
            </td>
        </tr>
        <tr>
            <td>Three</td>
            <td>
                <input type="checkbox" />
            </td>
        </tr>
    </tbody>
</table>

So now I have a child table which works the same way as the original table but I would also like the checkbox from the row in the parent table to work the same way as the header checkbox in the child table, so when all the checkboxes are checked in the child table, the header checkbox and the checkbox from the row in the parent table get checked.

To add a further level of complexity, I would ultimately like to use indeterminate states on the checkboxes if 'some' of the checkboxes are checked.

Here's the javascript/jQuery I have so far... I think the main thing that's not working is when the checkbox from the parent table gets automatically checked, the header checkbox from that parent table is not being checked if all rows are checked.

/* SEPARATE FROM THE OTHER 'ON CHANGE' CODE BECAUSE THIS IS USED ON ALL TABLES */
$(document).on('change', 'td input[type=checkbox]', function () {
    var ind = $(this).closest("td").index();
    check_checkbox($(this).closest('table'), ind);
});

$('table th input[type=checkbox]').click(function () {
    var checked = $(this).prop('checked');
    var ind = $(this).closest("th").index();
    $(this).closest('table').find('tbody tr').each(function () {
        $(this).find('td:eq(' + ind + ') input[type=checkbox]:not(:disabled)').prop('indeterminate',false).prop('checked', checked).trigger('change');
    });
});

function check_checkbox(table, pos) {
    if (!pos) pos = 0;
    var count = 0;
    var checked = 0;
    table.find("tbody tr").each(function () {
        count = count + $(this).find('td:eq(' + pos + ') input[type=checkbox]:not(:disabled)').length;
        checked = checked + $(this).find('td:eq(' + pos + ') input[type=checkbox]:checked').length;
    });
    table.find('th:eq(' + pos + ') input[type=checkbox]').prop('checked', count == checked && count > 0).prop('indeterminate',false).trigger('change');
}
/* *********************** */



$(document).on('change', '.parent-table td input[type=checkbox]', function() {
    var checkit = $(this).prop('checked');
    var a = $(this).closest('tr').attr('data-user-id');
    $("table#"+a).find("tr").each( function() {
        $(this).find("input[type=checkbox]").prop("checked", checkit);
    });
});

$(document).on('change', '.child-table td input[type=checkbox]', function() {
    var a = $(this).closest('table').attr('id');
    var b = $(this).closest("tbody").find("input[type=checkbox]").length;
    var c = $(this).closest("tbody").find("input[type=checkbox]:checked").length;
    if(b == c) {
        $("table tr[data-user-id="+a+"]").find("input[type=checkbox]").prop("checked", true).prop('indeterminate',false);
    } else if(c == 0) {
        $("table tr[data-user-id="+a+"]").find("input[type=checkbox]").prop("checked", false).prop('indeterminate',false);
    } else {
        $("table tr[data-user-id="+a+"]").find("input[type=checkbox]").prop("checked", true).prop('indeterminate',true);
    }
});

And here's a jsfiddle... http://jsfiddle.net/5cBTT/

1

1 Answers

1
votes

The problem is that in your check_checkbox() function, you are only updating header chkbox of the targeted table. For example, if you check all the boxes from the child table, you are updating the header boxe of this table but not the main one. What you should do is, in your

$(document).on('change', '.child-table td input[type=checkbox]', function() {

Add

check_checkbox($(".parent-table"),$(this).closest("td").index());

behind each

...").prop("checked", ...

here's a working fiddle

http://jsfiddle.net/TCHdevlp/5cBTT/1/

Also, I recommend you to bind checkboxes with the onchange event instead of counting checked boxes against boxes count. If one day, you want to use pagination in your tables, the count will only count visible checkboxes. So, if you check the "check all" box, only boxes of the current page will be checked. Also, each time your are checking a box, your are re-counting all the boxes of your page, wich can be a big number.