Search code examples
javascriptcheckboxtabulator

checkbox column selection issue in tabulator.js


I'm using Tabulator.js v4.2.7 and I have a checkbox column to select rows. This column header has a checkbox to select/deselect all rows.

This is working fine. But after clicking header checkbox all rows will be selected and if I uncheck any row checkbox then header checkbox is not getting unchecked.

Example, if I have 5 rows and if I click header checkbox the all 5 rows will be selected and now if I uncheck 2nd row checkbox remaining 4 rows will still be selected and header checkbox needs to be unchecked. But header checkbox is not getting unchecked.

Here is my code for checkbox column:

{
    title: 'Select <br/> All <br/> <input type="checkbox" class="select-all-row" aria-label="select all rows" />',
    field: 'IsSelected',
    formatter: function(cell, formatterParams, onRendered) {
        return '<input type="checkbox" class="select-row" aria-label="select this row" />';
    },
    width: 50,
    headerSort: false,
    headerFilter: false,
    cssClass: 'text-center',
    frozen: true,
    tooltips: false,
    resizable: false,
    cellClick: function(e, cell) {
        var $element = $(cell.getElement());
        var $chkbox = $element.find('.select-row');
        if (cell.getData().IsSelected) {
            cell.getRow().deselect();
        } else {
            cell.getRow().select();
        }
        $chkbox.prop('checked', !cell.getData().IsSelected);
        cell.getData().IsSelected = !cell.getData().IsSelected;
    },
    headerClick: function(e, column) {
        if (column.getTable().getSelectedRows().length !== column.getTable().getDataCount()) {
            $('.select-row,.select-all-row').prop('checked', true);
            column.getTable().selectRow();
        } else {
            $('.select-row,.select-all-row').prop('checked', false);
            column.getTable().deselectRow();
        }
    }
}

please assist on where I'm doing wrong.

Thanks,

Abdul


Solution

  • After analyzing for few hours I found where I was wrong. I resolved by setting the cell.getData().IsSelected for all cells in the column on header click and also added logic to uncheck header checkbox in cell click based on count. Also I have replaced Jquery code with vanilla javascript Here is the answer:

    Here is the working snippet

    var tabledata = [{
        id: 1,
        name: "Oli Bob",
        progress: 12,
        location: "United Kingdom",
        gender: "male",
        rating: 1,
        col: "red",
        dob: "14/04/1984",
        car: 1,
        lucky_no: 5,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 2,
        name: "Mary May",
        progress: 1,
        location: "Germany",
        gender: "female",
        rating: 2,
        col: "blue",
        dob: "14/05/1982",
        car: true,
        lucky_no: 10,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 3,
        name: "Christine Lobowski",
        progress: 42,
        location: "France",
        gender: "female",
        rating: 0,
        col: "green",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 12,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 4,
        name: "Brendon Philips",
        progress: 100,
        location: "USA",
        gender: "male",
        rating: 1,
        col: "orange",
        dob: "01/08/1980",
        car: false,
        lucky_no: 18,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 5,
        name: "Margret Marmajuke",
        progress: 16,
        location: "Canada",
        gender: "female",
        rating: 5,
        col: "yellow",
        dob: "31/01/1999",
        car: false,
        lucky_no: 33,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 6,
        name: "Frank Harbours",
        progress: 38,
        location: "Russia",
        gender: "male",
        rating: 4,
        col: "red",
        dob: "12/05/1966",
        car: 1,
        lucky_no: 2,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 7,
        name: "Jamie Newhart",
        progress: 23,
        location: "India",
        gender: "male",
        rating: 3,
        col: "green",
        dob: "14/05/1985",
        car: true,
        lucky_no: 63,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 8,
        name: "Gemma Jane",
        progress: 60,
        location: "China",
        gender: "female",
        rating: 0,
        col: "red",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 72,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 9,
        name: "Emily Sykes",
        progress: 42,
        location: "South Korea",
        gender: "female",
        rating: 1,
        col: "maroon",
        dob: "11/11/1970",
        car: false,
        lucky_no: 44,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 10,
        name: "James Newman",
        progress: 73,
        location: "Japan",
        gender: "male",
        rating: 5,
        col: "red",
        dob: "22/03/1998",
        car: false,
        lucky_no: 9,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 11,
        name: "Oli Bob",
        progress: 12,
        location: "United Kingdom",
        gender: "male",
        rating: 1,
        col: "red",
        dob: "14/04/1984",
        car: 1,
        lucky_no: 5,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 12,
        name: "Mary May",
        progress: 1,
        location: "Germany",
        gender: "female",
        rating: 2,
        col: "blue",
        dob: "14/05/1982",
        car: true,
        lucky_no: 10,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 13,
        name: "Christine Lobowski",
        progress: 42,
        location: "France",
        gender: "female",
        rating: 0,
        col: "green",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 12,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 14,
        name: "Brendon Philips",
        progress: 100,
        location: "USA",
        gender: "male",
        rating: 1,
        col: "orange",
        dob: "01/08/1980",
        car: false,
        lucky_no: 18,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 15,
        name: "Margret Marmajuke",
        progress: 16,
        location: "Canada",
        gender: "female",
        rating: 5,
        col: "yellow",
        dob: "31/01/1999",
        car: false,
        lucky_no: 33,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 16,
        name: "Frank Harbours",
        progress: 38,
        location: "Russia",
        gender: "male",
        rating: 4,
        col: "red",
        dob: "12/05/1966",
        car: 1,
        lucky_no: 2,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 17,
        name: "Jamie Newhart",
        progress: 23,
        location: "India",
        gender: "male",
        rating: 3,
        col: "green",
        dob: "14/05/1985",
        car: true,
        lucky_no: 63,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 18,
        name: "Gemma Jane",
        progress: 60,
        location: "China",
        gender: "female",
        rating: 0,
        col: "red",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 72,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 19,
        name: "Emily Sykes",
        progress: 42,
        location: "South Korea",
        gender: "female",
        rating: 1,
        col: "maroon",
        dob: "11/11/1970",
        car: false,
        lucky_no: 44,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 20,
        name: "James Newman",
        progress: 73,
        location: "Japan",
        gender: "male",
        rating: 5,
        col: "red",
        dob: "22/03/1998",
        car: false,
        lucky_no: 9,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 21,
        name: "Oli Bob",
        progress: 12,
        location: "United Kingdom",
        gender: "male",
        rating: 1,
        col: "red",
        dob: "14/04/1984",
        car: 1,
        lucky_no: 5,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 22,
        name: "Mary May",
        progress: 1,
        location: "Germany",
        gender: "female",
        rating: 2,
        col: "blue",
        dob: "14/05/1982",
        car: true,
        lucky_no: 10,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 23,
        name: "Christine Lobowski",
        progress: 42,
        location: "France",
        gender: "female",
        rating: 0,
        col: "green",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 12,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 24,
        name: "Brendon Philips",
        progress: 100,
        location: "USA",
        gender: "male",
        rating: 1,
        col: "orange",
        dob: "01/08/1980",
        car: false,
        lucky_no: 18,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 25,
        name: "Margret Marmajuke",
        progress: 16,
        location: "Canada",
        gender: "female",
        rating: 5,
        col: "yellow",
        dob: "31/01/1999",
        car: false,
        lucky_no: 33,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 26,
        name: "Frank Harbours",
        progress: 38,
        location: "Russia",
        gender: "male",
        rating: 4,
        col: "red",
        dob: "12/05/1966",
        car: 1,
        lucky_no: 2,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 27,
        name: "Jamie Newhart",
        progress: 23,
        location: "India",
        gender: "male",
        rating: 3,
        col: "green",
        dob: "14/05/1985",
        car: true,
        lucky_no: 63,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 28,
        name: "Gemma Jane",
        progress: 60,
        location: "China",
        gender: "female",
        rating: 0,
        col: "red",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 72,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 29,
        name: "Emily Sykes",
        progress: 42,
        location: "South Korea",
        gender: "female",
        rating: 1,
        col: "maroon",
        dob: "11/11/1970",
        car: false,
        lucky_no: 44,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 30,
        name: "James Newman",
        progress: 73,
        location: "Japan",
        gender: "male",
        rating: 5,
        col: "red",
        dob: "22/03/1998",
        car: false,
        lucky_no: 9,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 31,
        name: "Oli Bob",
        progress: 12,
        location: "United Kingdom",
        gender: "male",
        rating: 1,
        col: "red",
        dob: "14/04/1984",
        car: 1,
        lucky_no: 5,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 32,
        name: "Mary May",
        progress: 1,
        location: "Germany",
        gender: "female",
        rating: 2,
        col: "blue",
        dob: "14/05/1982",
        car: true,
        lucky_no: 10,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 33,
        name: "Christine Lobowski",
        progress: 42,
        location: "France",
        gender: "female",
        rating: 0,
        col: "green",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 12,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 34,
        name: "Brendon Philips",
        progress: 100,
        location: "USA",
        gender: "male",
        rating: 1,
        col: "orange",
        dob: "01/08/1980",
        car: false,
        lucky_no: 18,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 35,
        name: "Margret Marmajuke",
        progress: 16,
        location: "Canada",
        gender: "female",
        rating: 5,
        col: "yellow",
        dob: "31/01/1999",
        car: false,
        lucky_no: 33,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 36,
        name: "Frank Harbours",
        progress: 38,
        location: "Russia",
        gender: "male",
        rating: 4,
        col: "red",
        dob: "12/05/1966",
        car: 1,
        lucky_no: 2,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 37,
        name: "Jamie Newhart",
        progress: 23,
        location: "India",
        gender: "male",
        rating: 3,
        col: "green",
        dob: "14/05/1985",
        car: true,
        lucky_no: 63,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 38,
        name: "Gemma Jane",
        progress: 60,
        location: "China",
        gender: "female",
        rating: 0,
        col: "red",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 72,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 39,
        name: "Emily Sykes",
        progress: 42,
        location: "South Korea",
        gender: "female",
        rating: 1,
        col: "maroon",
        dob: "11/11/1970",
        car: false,
        lucky_no: 44,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 40,
        name: "James Newman",
        progress: 73,
        location: "Japan",
        gender: "male",
        rating: 5,
        col: "red",
        dob: "22/03/1998",
        car: false,
        lucky_no: 9,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 41,
        name: "Oli Bob",
        progress: 12,
        location: "United Kingdom",
        gender: "male",
        rating: 1,
        col: "red",
        dob: "14/04/1984",
        car: 1,
        lucky_no: 5,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 42,
        name: "Mary May",
        progress: 1,
        location: "Germany",
        gender: "female",
        rating: 2,
        col: "blue",
        dob: "14/05/1982",
        car: true,
        lucky_no: 10,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 43,
        name: "Christine Lobowski",
        progress: 42,
        location: "France",
        gender: "female",
        rating: 0,
        col: "green",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 12,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 44,
        name: "Brendon Philips",
        progress: 100,
        location: "USA",
        gender: "male",
        rating: 1,
        col: "orange",
        dob: "01/08/1980",
        car: false,
        lucky_no: 18,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 45,
        name: "Margret Marmajuke",
        progress: 16,
        location: "Canada",
        gender: "female",
        rating: 5,
        col: "yellow",
        dob: "31/01/1999",
        car: false,
        lucky_no: 33,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 46,
        name: "Frank Harbours",
        progress: 38,
        location: "Russia",
        gender: "male",
        rating: 4,
        col: "red",
        dob: "12/05/1966",
        car: 1,
        lucky_no: 2,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 47,
        name: "Jamie Newhart",
        progress: 23,
        location: "India",
        gender: "male",
        rating: 3,
        col: "green",
        dob: "14/05/1985",
        car: true,
        lucky_no: 63,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 48,
        name: "Gemma Jane",
        progress: 60,
        location: "China",
        gender: "female",
        rating: 0,
        col: "red",
        dob: "22/05/1982",
        car: "true",
        lucky_no: 72,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 49,
        name: "Emily Sykes",
        progress: 42,
        location: "South Korea",
        gender: "female",
        rating: 1,
        col: "maroon",
        dob: "11/11/1970",
        car: false,
        lucky_no: 44,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
      {
        id: 50,
        name: "James Newman",
        progress: 73,
        location: "Japan",
        gender: "male",
        rating: 5,
        col: "red",
        dob: "22/03/1998",
        car: false,
        lucky_no: 9,
        lorem: "Lorem ipsum dolor sit amet, elit consectetur adipisicing "
      },
    ];
    
    var table = new Tabulator("#example-table", {
      data: tabledata,
      columns: [{
          title: 'Select <br/> All <br/> <input type="checkbox" class="select-all-row" aria-label="select all rows" />',
          field: 'IsSelected',
          formatter: function(cell, formatterParams, onRendered) {
            return '<input type="checkbox" class="select-row" aria-label="select this row" />';
          },
          width: 50,
          headerSort: false,
          headerFilter: false,
          cssClass: 'text-center',
          frozen: true,
          tooltips: false,
          resizable: false,
          cellClick: function(e, cell) {
            var element = cell.getElement();
            var chkbox = element.querySelector('.select-row');
            if (cell.getData().IsSelected) {
              cell.getRow().deselect();
              document.querySelector('.select-all-row').checked = false;
            } else {
              cell.getRow().select();
              if (cell.getColumn().getTable().getSelectedRows().length === cell.getColumn().getTable().getDataCount()) {
                document.querySelector('.select-all-row').checked = true;
              }
            }
            chkbox.checked = !cell.getData().IsSelected;
            cell.getData().IsSelected = !cell.getData().IsSelected;
          },
          headerClick: function(e, column) {
            if (column.getTable().getSelectedRows().length !== column.getTable().getDataCount()) {
              document.querySelectorAll('.select-row,.select-all-row').forEach(cb => cb.checked = true);
              column.getTable().selectRow();
            } else {
              document.querySelectorAll('.select-row,.select-all-row').forEach(cb => cb.checked = false);
              column.getTable().deselectRow();
            }
            column.getCells().forEach(cell => cell.getData().IsSelected = !cell.getData().IsSelected);
          }
        },
        {
          title: "Name",
          field: "name",
          width: 200
        },
        {
          title: "Progress",
          field: "progress",
          width: 100,
          align: "right",
          sorter: "number"
        },
        {
          title: "Gender",
          field: "gender",
          width: 100
        },
        {
          title: "Rating",
          field: "rating",
          align: "center",
          width: 80
        },
      ],
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.2.7/css/tabulator.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.2.7/js/tabulator.min.js"></script>
    <div id="example-table"></div>