Solution 1 :

‘select.dt deselect.dt’ will be triggered when you click the select-all checkbox. And countItems is NOT the count of filtered item but the all items. so you should change countItems to myProductGapsTable.rows({search: ‘applied’}).count() as below:

var countItems = myProductGapsTable.rows({search: 'applied'}).count()

Problem :

I am working on a table with data where one of the columns is a checkbox, and the user can check which rows they want to be exported to csv / excel files.

My jsfiddle example works correctly for non filtered data, if the table searchbox is empty and you click the ‘select all’ column, it will accurately select all and deselect all.
enter image description here

But if you search for something like ‘x’, and then click the ‘select all’ first column checkbox, it selects all results but doesnt reflect the change in the column checkbox?
enter image description here

My datatable is declared like so:

    var myProductGapsTable = $('#myProductGapsTable').DataTable({
    data: dataSet,
    retrieve: true,  
    "language": { "emptyTable": "No table data availiable."},
    "sDom": 'Bfrtip',
    "paging": false,
     buttons: [
                     extend: 'excelHtml5',
                     text: 'excel',
                     //exportOptions: {  modifier: {  page: 'current' }  }
                     exportOptions: { rows: { selected: true, search: 'applied' } }

                     extend: 'csvHtml5',
                     text: 'csv',
                     exportOptions: { rows: { selected: true, search: 'applied' } }
    responsive: {
        details: {
            type: 'column',
            target: -1,
    columnDefs: [ {
        targets: -1,
        orderable: false,
        searchable: false,
        className: 'control',
    }, {
        targets: 0,
        orderable: false,
        searchable: false,
        className: 'selectall-checkbox',
    } ],
    select: {
        style: 'multi',
        selector: 'td:first-child',
        search: 'applied'
    order: [ 1, 'asc' ],

And I’m using the following 3 functions to handle the checkboxes and what happens when you click ‘select all’:

    // On DataTables select / deselect event check / uncheck all checkboxes. And deal with the checkbox
// in the thead (check or uncheck).
myProductGapsTable.on('select.dt deselect.dt', function (e, dt, type, indexes){
    var countSelectedRows = myProductGapsTable.rows( {selected: true} ).count()
    var countItems = myProductGapsTable.rows().count()

    if (countItems > 0) {
        console.log("~ countItems > 0")
        if (countSelectedRows == countItems){
            $('thead .selectall-checkbox input[type="checkbox"]', this).prop('checked', true);
        } else {
            $('thead .selectall-checkbox input[type="checkbox"]', this).prop('checked', false);

    if (e.type === 'select') {
        $('.selectall-checkbox input[type="checkbox"]', myProductGapsTable.rows({search: 'applied', selected: true}).nodes()).prop('checked', true);
    } else {
        $('.selectall-checkbox input[type="checkbox"]', myProductGapsTable.rows({selected: false}).nodes()).prop('checked', false);

// When clicking on "thead .selectall-checkbox", trigger click on checkbox in that cell.
myProductGapsTable.on('click', 'thead .selectall-checkbox', function() {
    $('input[type="checkbox"]', myProductGapsTable.rows({ search: 'applied', selected: true })).trigger('click');

// When clicking on the checkbox in "thead .selectall-checkbox", define the actions.
myProductGapsTable.on('click', 'thead .selectall-checkbox input[type="checkbox"]', function(e) {
    if (this.checked) {
        myProductGapsTable.rows({ search: 'applied' }).select();
    } else {
        myProductGapsTable.rows({ search: 'applied'}).deselect();