[jquery] Datatables Select All Checkbox

The demo on the select all doesn't really work. https://datatables.net/extensions/select/examples/initialisation/checkbox.html

What's the best way to implement the select all checkbox after they are created via the columnDef attributes?

This question is related to jquery datatables

The answer is


You can use Checkboxes extension for jQuery Datatables.

var table = $('#example').DataTable({
   'ajax': 'https://api.myjson.com/bins/1us28',
   'columnDefs': [
      {
         'targets': 0,
         'checkboxes': {
            'selectRow': true
         }
      }
   ],
   'select': {
      'style': 'multi'
   },
   'order': [[1, 'asc']]
});

See this example for code and demonstration.

See Checkboxes project page for more examples and documentation.


I made a simple implementation of this functionality using fontawesome, also taking advantage of the Select Extension, this covers select all, deselect some items, deselect all. https://codepen.io/pakogn/pen/jJryLo

HTML:

<table id="example" class="display" style="width:100%">
    <thead>
        <tr>
            <th>
                <button style="border: none; background: transparent; font-size: 14px;" id="MyTableCheckAllButton">
                <i class="far fa-square"></i>  
                </button>
            </th>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Salary</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td>Tiger Nixon</td>
            <td>System Architect</td>
            <td>Edinburgh</td>
            <td>61</td>
            <td>$320,800</td>
        </tr>
        <tr>
            <td></td>
            <td>Garrett Winters</td>
            <td>Accountant</td>
            <td>Tokyo</td>
            <td>63</td>
            <td>$170,750</td>
        </tr>
        <tr>
            <td></td>
            <td>Ashton Cox</td>
            <td>Junior Technical Author</td>
            <td>San Francisco</td>
            <td>66</td>
            <td>$86,000</td>
        </tr>
        <tr>
            <td></td>
            <td>Cedric Kelly</td>
            <td>Senior Javascript Developer</td>
            <td>Edinburgh</td>
            <td>22</td>
            <td>$433,060</td>
        </tr>
        <tr>
            <td></td>
            <td>Airi Satou</td>
            <td>Accountant</td>
            <td>Tokyo</td>
            <td>33</td>
            <td>$162,700</td>
        </tr>
        <tr>
            <td></td>
            <td>Brielle Williamson</td>
            <td>Integration Specialist</td>
            <td>New York</td>
            <td>61</td>
            <td>$372,000</td>
        </tr>
        <tr>
            <td></td>
            <td>Herrod Chandler</td>
            <td>Sales Assistant</td>
            <td>San Francisco</td>
            <td>59</td>
            <td>$137,500</td>
        </tr>
        <tr>
            <td></td>
            <td>Rhona Davidson</td>
            <td>Integration Specialist</td>
            <td>Tokyo</td>
            <td>55</td>
            <td>$327,900</td>
        </tr>
        <tr>
            <td></td>
            <td>Colleen Hurst</td>
            <td>Javascript Developer</td>
            <td>San Francisco</td>
            <td>39</td>
            <td>$205,500</td>
        </tr>
        <tr>
            <td></td>
            <td>Sonya Frost</td>
            <td>Software Engineer</td>
            <td>Edinburgh</td>
            <td>23</td>
            <td>$103,600</td>
        </tr>
        <tr>
            <td></td>
            <td>Jena Gaines</td>
            <td>Office Manager</td>
            <td>London</td>
            <td>30</td>
            <td>$90,560</td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <th></th>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Salary</th>
        </tr>
    </tfoot>
</table>

Javascript:

$(document).ready(function() {
    let myTable = $('#example').DataTable({
        columnDefs: [{
            orderable: false,
            className: 'select-checkbox',
            targets: 0,
        }],
        select: {
            style: 'os', // 'single', 'multi', 'os', 'multi+shift'
            selector: 'td:first-child',
        },
        order: [
            [1, 'asc'],
        ],
    });

    $('#MyTableCheckAllButton').click(function() {
        if (myTable.rows({
                selected: true
            }).count() > 0) {
            myTable.rows().deselect();
            return;
        }

        myTable.rows().select();
    });

    myTable.on('select deselect', function(e, dt, type, indexes) {
        if (type === 'row') {
            // We may use dt instead of myTable to have the freshest data.
            if (dt.rows().count() === dt.rows({
                    selected: true
                }).count()) {
                // Deselect all items button.
                $('#MyTableCheckAllButton i').attr('class', 'far fa-check-square');
                return;
            }

            if (dt.rows({
                    selected: true
                }).count() === 0) {
                // Select all items button.
                $('#MyTableCheckAllButton i').attr('class', 'far fa-square');
                return;
            }

            // Deselect some items button.
            $('#MyTableCheckAllButton i').attr('class', 'far fa-minus-square');
        }
    });
});

The solution given by @annoyingmouse works for me.

But to use the checkbox in the header cell, I also had to fix select.dataTables.css.
It seems that they used :

table.dataTable tbody th.select-checkbox

instead of :

table.dataTable thead th.select-checkbox

So I had to add this to my css :

table.dataTable thead th.select-checkbox {
  position: relative;
}
table.dataTable thead th.select-checkbox:before,
table.dataTable thead th.select-checkbox:after {
  display: block;
  position: absolute;
  top: 1.2em;
  left: 50%;
  width: 12px;
  height: 12px;
  box-sizing: border-box;
}
table.dataTable tbody td.select-checkbox:before,
table.dataTable thead th.select-checkbox:before {
  content: ' ';
  margin-top: -6px;
  margin-left: -6px;
  border: 1px solid black;
  border-radius: 3px;
}

You can use this option provided by dataTable itself using buttons.

dom: 'Bfrtip',
 buttons: [
      'selectAll',
      'selectNone'
 ]'

Here is a sample code

var tableFaculty = $('#tableFaculty').DataTable({
    "columns": [
        {
            data: function (row, type, set) {
                return '';
            }
        },
        {data: "NAME"}
    ],
    "columnDefs": [
        {
            orderable: false,
            className: 'select-checkbox',
            targets: 0
        }
    ],
    select: {
        style: 'multi',
        selector: 'td:first-child'
    },
    dom: 'Bfrtip',
    buttons: [
        'selectAll',
        'selectNone'
    ],
    "order": [[0, 'desc']]
});

Base on Francisco Daniel's answer I modified some of the Jquery code here's My version. I removed some excess code and use "fa" instead of "far" for the icon. I also remove the "far fa-minus-square" since I can't understand its purpose.

-- Edited --

I added the "draw" event for the button icon to update whenever the table is redrawn or reloaded. Because I noticed when I tried to reload the table using "myTable.ajax.reload()" the button icon is not changing.

https://codepen.io/john-kenneth-larbo/pen/zXeYpz

_x000D_
_x000D_
$(document).ready(function() {_x000D_
    let myTable = $('#example').DataTable({_x000D_
        columnDefs: [{_x000D_
            orderable: false,_x000D_
            className: 'select-checkbox',_x000D_
            targets: 0,_x000D_
        }],_x000D_
        select: {_x000D_
            style: 'os', // 'single', 'multi', 'os', 'multi+shift'_x000D_
            selector: 'td:first-child',_x000D_
        },_x000D_
        order: [_x000D_
            [1, 'asc'],_x000D_
        ],_x000D_
    });_x000D_
_x000D_
       myTable.on('select deselect draw', function () {_x000D_
        var all = myTable.rows({ search: 'applied' }).count(); // get total count of rows_x000D_
        var selectedRows = myTable.rows({ selected: true, search: 'applied' }).count(); // get total count of selected rows_x000D_
_x000D_
        if (selectedRows < all) {_x000D_
            $('#MyTableCheckAllButton i').attr('class', 'fa fa-square-o');_x000D_
        } else {_x000D_
            $('#MyTableCheckAllButton i').attr('class', 'fa fa-check-square-o');_x000D_
        }_x000D_
_x000D_
    });_x000D_
_x000D_
    $('#MyTableCheckAllButton').click(function () {_x000D_
        var all = myTable.rows({ search: 'applied' }).count(); // get total count of rows_x000D_
        var selectedRows = myTable.rows({ selected: true, search: 'applied' }).count(); // get total count of selected rows_x000D_
_x000D_
_x000D_
        if (selectedRows < all) {_x000D_
            //Added search applied in case user wants the search items will be selected_x000D_
            myTable.rows({ search: 'applied' }).deselect();_x000D_
            myTable.rows({ search: 'applied' }).select();_x000D_
        } else {_x000D_
            myTable.rows({ search: 'applied' }).deselect();_x000D_
        }_x000D_
    });_x000D_
});
_x000D_
<table id="example" class="display" style="width:100%">_x000D_
    <thead>_x000D_
        <tr>_x000D_
            <th>_x000D_
                <button style="border: none; background: transparent; font-size: 14px;" id="MyTableCheckAllButton">_x000D_
                <i class="far fa-square"></i>  _x000D_
                </button>_x000D_
            </th>_x000D_
            <th>Name</th>_x000D_
            <th>Position</th>_x000D_
            <th>Office</th>_x000D_
            <th>Age</th>_x000D_
            <th>Salary</th>_x000D_
        </tr>_x000D_
    </thead>_x000D_
    <tbody>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Tiger Nixon</td>_x000D_
            <td>System Architect</td>_x000D_
            <td>Edinburgh</td>_x000D_
            <td>61</td>_x000D_
            <td>$320,800</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Garrett Winters</td>_x000D_
            <td>Accountant</td>_x000D_
            <td>Tokyo</td>_x000D_
            <td>63</td>_x000D_
            <td>$170,750</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Ashton Cox</td>_x000D_
            <td>Junior Technical Author</td>_x000D_
            <td>San Francisco</td>_x000D_
            <td>66</td>_x000D_
            <td>$86,000</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Cedric Kelly</td>_x000D_
            <td>Senior Javascript Developer</td>_x000D_
            <td>Edinburgh</td>_x000D_
            <td>22</td>_x000D_
            <td>$433,060</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Airi Satou</td>_x000D_
            <td>Accountant</td>_x000D_
            <td>Tokyo</td>_x000D_
            <td>33</td>_x000D_
            <td>$162,700</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Brielle Williamson</td>_x000D_
            <td>Integration Specialist</td>_x000D_
            <td>New York</td>_x000D_
            <td>61</td>_x000D_
            <td>$372,000</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Herrod Chandler</td>_x000D_
            <td>Sales Assistant</td>_x000D_
            <td>San Francisco</td>_x000D_
            <td>59</td>_x000D_
            <td>$137,500</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Rhona Davidson</td>_x000D_
            <td>Integration Specialist</td>_x000D_
            <td>Tokyo</td>_x000D_
            <td>55</td>_x000D_
            <td>$327,900</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Colleen Hurst</td>_x000D_
            <td>Javascript Developer</td>_x000D_
            <td>San Francisco</td>_x000D_
            <td>39</td>_x000D_
            <td>$205,500</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Sonya Frost</td>_x000D_
            <td>Software Engineer</td>_x000D_
            <td>Edinburgh</td>_x000D_
            <td>23</td>_x000D_
            <td>$103,600</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td></td>_x000D_
            <td>Jena Gaines</td>_x000D_
            <td>Office Manager</td>_x000D_
            <td>London</td>_x000D_
            <td>30</td>_x000D_
            <td>$90,560</td>_x000D_
        </tr>_x000D_
    </tbody>_x000D_
    <tfoot>_x000D_
        <tr>_x000D_
            <th></th>_x000D_
            <th>Name</th>_x000D_
            <th>Position</th>_x000D_
            <th>Office</th>_x000D_
            <th>Age</th>_x000D_
            <th>Salary</th>_x000D_
        </tr>_x000D_
    </tfoot>_x000D_
</table>
_x000D_
_x000D_
_x000D_