Home > Back-end >  Datatables - how to retain filter data and reassign them to dropdowns
Datatables - how to retain filter data and reassign them to dropdowns

Time:10-04

I'm using Jquery datatables and it has filters in the form of dropdowns. The HTML looks like below.

<table id="example">
   <thead>
     <tr>
       <th>Name</th>
       <th>Position</th>
       <th>Office</th>
       <th>Age</th>
       <th>Start date</th>
       <th>Salary</th>
     </tr>
     <tr>
       <td></td>
       <td><select><option>-Filter-</option></select></td>
       <td><select><option>-Filter-</option></select></td>
       <td></td>
       <td></td>
       <td></td>
     </tr>
   </thead>
   <tbody>
     <tr>
       <td>Tiger Nixon</td>
       <td>System Architect</td>
       <td>Edinburgh</td>
       <td>61</td>
       <td>2011-04-25</td>
       <td>$320,800</td>
     </tr>
     <tr>
       <td>Tiger Nixon</td>
       <td>System Architect</td>
       <td>Edinburgh</td>
       <td>61</td>
       <td>2011-04-25</td>
       <td>$320,800</td>
     </tr>
   </tbody>
  </table>

Filter dropdown can be in any column as this is used in many places with different datasets. Therefore, I've made it dynamic with the use of Datatable's provided method and managed to get as far as locating the <td> element with the filter dropdown.

var filterColumn = $("#example thead tr:eq(1) td:eq("   i   ") select");

In the code snippet above, i being the column number which comes from the overarching function and successfully get assigned inside td:eq, however, my Jquery selector won't return the dropdown inside the table cell, instead returns Jquery Object as below.

enter image description here

Any help is much appreciated to fix the selector.

JS bin - https://jsbin.com/badopohino/edit?html,js,output

Thanks.

$('#example').DataTable({
  orderCellsTop: true,
  stateSave: true,
  initComplete: function() {
    this.api()
      .columns([1, 2])
      .every(function() {
        var column = this;
        var select = $('<select ><option value=""> -- Filter -- </option></select>')
          .appendTo($('thead tr:eq(1) td:eq('   this.index()   ')'))
          .on('change', function() {
            var val = $.fn.dataTable.util.escapeRegex(
              $(this).val()
            );
            column
              .search(val ? '^'   val   '$' : '', true, false)
              .draw();
          });

        column.data().unique().sort().each(function(d, j) {
          if (!d == '') {
            select.append('<option value="'   d   '">'   d   '</option>');
          }
        });
      });
  },
  stateLoadParams: function(settings, data) {
    for (i = 0; i < data.columns["length"]; i  ) {
      var col_search_val = data.columns[i].search.search;

      if (col_search_val != "") {
        var filterColumn = $("#example thead tr:eq(1) td:eq("   i   ") select");
        console.log(filterColumn, i);
      }
    }
  }


});

var abc = $("#example thead tr:eq(1) td:eq(1) select");

//console.log(abc);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <!DOCTYPE html>
  <html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="//cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
    <title>JS Bin</title>
  </head>

  <body>
    <table id="example" >
      <thead>
        <tr>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Age</th>
          <th>Start date</th>
          <th>Salary</th>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Tiger Nixon</td>
          <td>System Architect</td>
          <td>Edinburgh</td>
          <td>61</td>
          <td>2011-04-25</td>
          <td>$320,800</td>
        </tr>
        <tr>
          <td>Garrett Winters</td>
          <td>Accountant</td>
          <td>Tokyo</td>
          <td>63</td>
          <td>2011-07-25</td>
          <td>$170,750</td>
        </tr>
        <tr>
          <td>Ashton Cox</td>
          <td>Junior Technical Author</td>
          <td>San Francisco</td>
          <td>66</td>
          <td>2009-01-12</td>
          <td>$86,000</td>
        </tr>
        <tr>
          <td>Cedric Kelly</td>
          <td>Senior Javascript Developer</td>
          <td>Edinburgh</td>
          <td>22</td>
          <td>2012-03-29</td>
          <td>$433,060</td>
        </tr>
        <tr>
          <td>Airi Satou</td>
          <td>Accountant</td>
          <td>Tokyo</td>
          <td>33</td>
          <td>2008-11-28</td>
          <td>$162,700</td>
        </tr>
        <tr>
          <td>Brielle Williamson</td>
          <td>Integration Specialist</td>
          <td>New York</td>
          <td>61</td>
          <td>2012-12-02</td>
          <td>$372,000</td>
        </tr>
      </tbody>
    </table>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script src="//cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>

  </body>

  </html>
</body>

</html>

CodePudding user response:

Managed to solve this by saving the filter data within the stateLoadParms method and then looping through them in the initComplete method and setting the selected value to the dropdown. Haven't tested the code below but what I was missing was that the Jquery selector couldn't find the dropdown elements inside table cells as they are added to the DOM later, as pointed out above by @Barmar.

var filterData = [];
$('#example').DataTable({
  orderCellsTop: true,
  stateSave: true,
  initComplete: function() {
    this.api()
      .columns([1, 2])
      .every(function(index) {
        var column = this;
        var select = $('<select ><option value=""> -- Filter -- </option></select>')
          .appendTo($('thead tr:eq(1) td:eq('   this.index()   ')'))
          .on('change', function() {
            var val = $.fn.dataTable.util.escapeRegex(
              $(this).val()
            );
            column
              .search(val ? '^'   val   '$' : '', true, false)
              .draw();
          });

        var option;
        column.data().unique().sort().each(function(d, j) {
          if (!d == '') {
            option = $('<option value="'   d   '">'   d   '</option>');
            if (d == filterData[index]) {
              option.prop('selected', true);
            }
            select.append(option);
          }
        });

      });
  },
  stateLoadParams: function(settings, data) {
    data.columns.forEach(function(col, i) {
      filterData.push(col.search.search);
    });
  }
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <!DOCTYPE html>
  <html>

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="//cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
    <title>JS Bin</title>
  </head>

  <body>
    <table id="example" >
      <thead>
        <tr>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Age</th>
          <th>Start date</th>
          <th>Salary</th>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Tiger Nixon</td>
          <td>System Architect</td>
          <td>Edinburgh</td>
          <td>61</td>
          <td>2011-04-25</td>
          <td>$320,800</td>
        </tr>
        <tr>
          <td>Garrett Winters</td>
          <td>Accountant</td>
          <td>Tokyo</td>
          <td>63</td>
          <td>2011-07-25</td>
          <td>$170,750</td>
        </tr>
        <tr>
          <td>Ashton Cox</td>
          <td>Junior Technical Author</td>
          <td>San Francisco</td>
          <td>66</td>
          <td>2009-01-12</td>
          <td>$86,000</td>
        </tr>
        <tr>
          <td>Cedric Kelly</td>
          <td>Senior Javascript Developer</td>
          <td>Edinburgh</td>
          <td>22</td>
          <td>2012-03-29</td>
          <td>$433,060</td>
        </tr>
        <tr>
          <td>Airi Satou</td>
          <td>Accountant</td>
          <td>Tokyo</td>
          <td>33</td>
          <td>2008-11-28</td>
          <td>$162,700</td>
        </tr>
        <tr>
          <td>Brielle Williamson</td>
          <td>Integration Specialist</td>
          <td>New York</td>
          <td>61</td>
          <td>2012-12-02</td>
          <td>$372,000</td>
        </tr>
      </tbody>
    </table>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    <script src="//cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>

  </body>

  </html>
</body>

</html>

  • Related