datatables callback on pagination

1.5k views Asked by At

I'm implementing switchery into datatable in this way

UPDATE

  var table = $('#table').DataTable({
        pageLength: 25,
        responsive: true,
        deferRender: true,
        stateSave: false,
        info: false,
        ordering: false,
        dom: 'lTfgt<"float-left"i>p',
        ajax: {
            "url": "../src/routes.php",
            "type": "POST",
            "async":true,
            "dataType": "json",
            "data": function(d) {
                d.call = "data-vol";
                d.dataform = $('#filtroForm').serialize();
                d.market = JSON.stringify($('#jstree_topmarket').jstree("get_selected"));

                return d;
            }
        },
        language: {
            "url": "assets/js/plugins/dataTables/it_IT.txt"
        },
        "fnDrawCallback": function() {
            var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));

            elems.forEach(function(html) {
                var switchery = new Switchery(html, { size: 'small' });
            });
        }
    });

and seems ok

enter image description here

but when I switch to page 2 and then come back to page 1, I have this result

enter image description here

EDIT

Replacing fnDrawCallback with initComplete seems not working

enter image description here

2

There are 2 answers

9
andrewJames On

I would recommend using an initComplete function instead of drawCallback. This will avoid the problem you are seeing where you get new sliders added every time there is another draw event in your DataTable.

To access the checkbox nodes from initComplete you can use this:

"initComplete": function() {
  var allNodes = $('#example').DataTable().cells().nodes();
  $.each($( '.js-switch', allNodes), function(index, node) {
    var switchery = new Switchery(node, { size: 'small' });
  });   
}

The first line of the function uses the Datatables API to access every node in the table.

allNodes is a collection of <td> nodes - so then we have to select only those which contain a child node which uses your js-switch class.

Since we already have jQuery, I chose to use its iterator $.each() to iterate over al these checkbox nodes, to create the switchery object.


Update:

Here is the full DataTable I am using to test with:

$('#example').DataTable( {
  data: dataSet,
  columns: [
    { title: "Name", data: "name" },
    { title: "Office", data: "office" },
    { title: "Position", data: "position" },
    { title: "", defaultContent: '<input type="checkbox" class="js-switch" checked />' }
  ],
  "initComplete": function() {
    var allNodes = $('#example').DataTable().cells().nodes();
    $.each($( '.js-switch', allNodes), function(index, node) {
      var switchery = new Switchery(node, { size: 'small' });
    }); 
  }

} ); 

My test data is in a JavaScript variable:

var dataSet = [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": "5421"
    },

    // more data not shown here...

    {
      "id": "57",
      "name": "Donna Snider",
      "position": "Customer Support",
      "salary": "$112,000",
      "start_date": "2011/01/25",
      "office": "New York",
      "extn": "4226"
    }
  ];
0
Antón Casais Mera On

I use createdRow, this is my code:

createdRow: function (row) {
    initializeSwitchElement(row)
}


function initializeSwitchElement(row) {
    let checkbox = Array.prototype.slice.call($(row).find('.js-switch'));
    if ($(checkbox).prop('checked')) {
        $(checkbox).trigger('keyup').blur()
    }
    checkbox.forEach(function (element) {
        new Switchery(element, { size: 'small' });
    });
}