Question

I have the following Javascript function that is called when a change is made to one of my five "select-all" buttons of the class 'checkAllAud'. I basically have 5 vertical rows with possibly hundreds of checkboxes under each that need to be checked/unchecked.

My current code has problems with it when you want to click select all on all 5 columns, only every other column has all of its checkboxes selected. So my question is how can I rewrite this code so it will work with my multiple instances of select all columns and checkboxes.

var toggle = true;
    //on click function  here
    $(".checkAllAud").change(function() {
        var toggled = $(this).val();
                //alert('checkallaud function triggered');
                toggleBox(toggled);
            });
    //end on click function
    function toggleBox(toggled) {
        var objList = document.getElementsByName(toggled)
    //alert('toggleBox function triggered');
    for(i = 0; i < objList.length; i++)
        objList[i].checked = toggle;

    toggle = !toggle;
}

here is how my code currently works

            column1   column 2   column 3   column 4   column 5
(select all) [x]        [x]         [x]        [x]        [x]
             [x]        [ ]         [x]        [ ]        [x]

JSFiddle: http://jsfiddle.net/8KQcp/8/

Was it helpful?

Solution

You don't need to use a global, just take the checked state from the input you changed ;-)

$(".checkAllAud").change(function() {
   var toggled = $(this).val();
   //alert('checkallaud function triggered');
   toggleBox(toggled, this.checked);
});

function toggleBox(toggled, checked) {
   var objList = document.getElementsByName(toggled)
   //alert('toggleBox function triggered');
   for(i = 0; i < objList.length; i++)
      objList[i].checked = checked;

}

working jsFiddle: http://jsfiddle.net/8KQcp/9/


Improvement: http://jsbin.com/cakogulu/1/

$(".checkAllAud").change(function() {
   $('input[name^="' + this.value + '"]:checkbox').prop('checked', this.checked);
});

OTHER TIPS

You might consider a little html augmentation before you assign your event handlers.

Here is a fiddle for this example:

See fiddle example here

You need your javascript to iterate through an html structure that is repeatable. So, say you have an html structure like this: (see the fiddle)

<table class="jsSelectAll">
    <tbody>
        <tr class="select-all">
            <td>Select All</td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
        </tr>
        <tr>
            <td>Row Label</td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
        </tr>
        <tr>
            <td>Row Label</td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
        </tr>
    </tbody>
    <tbody>
        <tr class="select-all">
            <td>Select All</td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
        </tr>
        <tr>
            <td>Row Label</td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
            <td><input type="checkbox" /></td>
        </tr>
    </tbody>
</table>

Then, I would consider breaking out each table and tbody within the table as you need to, and add row (if desired) and column pointers to the checkboxes. Also, I would use closures to make the event wiring a bit easier, like this:

jQuery(function ($) {
    // closures
    var $tables = $('table.jsSelectAll');

    $tables.each(function () {
        // closures
        var $table = $(this);
        var $tbodies = $table.find('tbody');

        $tbodies.each(function () {
            // closures
            var $tbody = $(this);
            var $rows = $tbody.find('tr');
            var $selectAllCheckboxes = $tbody.find('.select-all input[type="checkbox"]');
            var $allCheckboxes = $tbody.find('tr td input[type="checkbox"]')

            // label data cells with rows(if desired) and collumns
            $rows.each(function (rowIndex) {
                // closures
                var $row = $(this);
                var $inputs = $row.find('input[type="checkbox"]');

                $row.attr('data-row', rowIndex);
                $inputs.each(function (colIndex) {
                    // closures
                    $cbx = $(this);

                    $cbx.attr('data-col', colIndex);
                });
            });

            // wire select all for each select-all row checkbox
            $selectAllCheckboxes.each(function () {
                // closures
                var $cbx = $(this)
                var fClick = function () {
                    var iCol = $cbx.attr('data-col');
                    $allCheckboxes
                        .filter('[data-col="' + iCol + '"]')
                        .each(function () {
                            $(this).prop('checked', true);
                        });
                };
                $cbx.click(fClick);
            });

        });
    });
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top