Skip to content
Advertisement

DataTables – this.api for multiple tables in callback function

I have followed this example to add dropdown filtering on my DataTables. It works fine when there is only 1 table on a page but I have a scenario where I have 2 tables.

As per the DataTables documentation (link 1, link 2), the API get access to all the DataTables instance at the same time.

So, I tried to target each table with something like

this.api().tables([0]).columns([3, 4]).every( function () {

but the filtering drop downs are appearing in the 1st table only.

 $('#table1').DataTable({
        "dom": '<"dtWrapper"<f>lrti<"paginate0rem"p>>',
        drawCallback: function(){
            if (feather) {
                feather.replace({
                    width: 14,
                    height: 14
                });
            }
        },
        orderCellsTop: true,
        initComplete: function () {
            this.api().tables([0]).columns([3, 4]).every( function () {
                let column = this,
                    select = $('<select class="form-control"><option value=""></option></select>')
                        .appendTo($('thead tr:eq(1) th:eq(' + this.index()  + ')'))
                        .on('change', function () {
                            let val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );

                            column
                                .search( val ? '^'+val+'$' : '', true, false)
                                .draw();
                        });

                column.data().unique().sort().each(function (d, j) {
                    select.append('<option value="'+d+'">'+d+'</option>')
                });
            });
        }
    });

    $('#table2').DataTable({
        "dom": '<"dtWrapper"<f>lrti<"paginate0rem"p>>',
        drawCallback: function(){
            if (feather) {
                feather.replace({
                    width: 14,
                    height: 14
                });
            }
        },
        orderCellsTop: true,
        initComplete: function () {
            this.api().tables([1]).columns([2, 3]).every( function () {
                let column = this,
                    select = $('<select class="form-control"><option value=""></option></select>')
                        .appendTo($('thead tr:eq(1) th:eq(' + this.index()  + ')'))
                        .on('change', function () {
                            let val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );

                            column
                                .search( val ? '^'+val+'$' : '', true, false)
                                .draw();
                        });

                column.data().unique().sort().each(function (d, j) {
                    select.append('<option value="'+d+'">'+d+'</option>')
                });
            });
        }
    });

Advertisement

Answer

  1. Calls to this.api().tables([0]) didn’t seem to work for the second table, as you will have noticed. I suspect this would work if you used two tables in one selector to create your DataTables (e.g. $("#table1, #table2").DataTables()). As such, changing this to use the actual selector of the required table e.g. $("#table1").DataTable().columns([2]) works much better. There may be a way of getting the “contextual” datatable without using the selector. But this should get you going in the right direction.

  2. Your .appendTo() call was attempting to select all the thead tr:eq(1) in your html. So, if you would have got the first step working, this broken appending would have caused problems.

See the demo with these fixes:

$(document).ready(function() {
  $('#table1').DataTable({
    "dom": '<"dtWrapper"<f>lrti<"paginate0rem"p>>',
    orderCellsTop: true,
    initComplete: function() {
      var $table = $("#table1");
      $table.DataTable().columns([2]).every(function() {
        let column = this;
        let select = $('<select class="form-control"><option value=""></option></select>')
          .appendTo($table.find('thead tr:eq(1) th:eq(' + this.index() + ')'))
          .on('change', function() {
            let val = $.fn.dataTable.util.escapeRegex($(this).val());

            column
              .search(val ? '^' + val + '$' : '', true, false)
              .draw();
          });

        column.data().unique().sort().each(function(d, j) {
          select.append('<option value="' + d + '">' + d + '</option>')
        });
      });
    }
  });

  $('#table2').DataTable({
    "dom": '<"dtWrapper"<f>lrti<"paginate0rem"p>>',
    orderCellsTop: true,
    initComplete: function() {
      var $table = $("#table2");

      $table.DataTable().columns([3]).every(function() {
        let column = this;
        let select = $('<select class="form-control"><option value=""></option></select>')
          .appendTo($table.find('thead tr:eq(1) th:eq(' + this.index() + ')'))
          .on('change', function() {
            let val = $.fn.dataTable.util.escapeRegex(
              $(this).val()
            );

            column
              .search(val ? '^' + val + '$' : '', true, false)
              .draw();
          });

        column.data().unique().sort().each(function(d, j) {
          select.append('<option value="' + d + '">' + d + '</option>')
        });
      });
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>



<!DOCTYPE html>
<html lang="en">
<link rel="stylesheet" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">

<body>
  <div>
    <table id="table1">
      <thead>
        <tr>
          <th>header 1</th>
          <th>header 2</th>
          <th>header 3</th>
          <th>header 4</th>
        </tr>
        <tr>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>col 1</td>
          <td>col 2</td>
          <td>col 3</td>
          <td>col 4</td>
        </tr>
        <tr>
          <td>col 1</td>
          <td>col 2</td>
          <td>col 3</td>
          <td>col 4</td>
        </tr>
      </tbody>
    </table>

    <table id="table2">
      <thead>
        <tr>
          <th>header 1</th>
          <th>header 2</th>
          <th>header 3</th>
          <th>header 4</th>
        </tr>
        <tr>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>col 1</td>
          <td>col 2</td>
          <td>col 3</td>
          <td>col 4</td>
        </tr>
        <tr>
          <td>col 1</td>
          <td>col 2</td>
          <td>col 3</td>
          <td>col 4</td>
        </tr>
      </tbody>
    </table>
  </div>

</body>
</html>
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement