user2964762
user2964762

Reputation: 93

Filtering the rows in DataTables

I currently have the JQuery plugin DataTables working correctly and I have inserted a button at the top of the page to filter the list further. (I have also used the search bar built into DataTables). I want the button to filter the table down and only show rows that contain a certain value.. Below is what ive been doing, but nothing seems to work.. In the example below I am trying to filter the list to all rows that contain the element 'Dog' within the 'Animal' column Anyone know how to fix this?

Thanks

$("#NewButton").click(function() {  
     $.fn.dataTable.ext.search.pop();
      table.draw();
    $.fn.dataTable.ext.search.push(
      function(settings, data, dataIndex) {
          return $(table.row(dataIndex).node()).attr(Animal) == "Dog";
        }
    );  
    table.draw();
    });

    $("#Default").click(function() {
    $.fn.dataTable.ext.search.pop();
    table.draw();
    });

Upvotes: 3

Views: 7827

Answers (1)

mhodges
mhodges

Reputation: 11116

Here's an example from my code -- it's with using <input> and <select>, but you should be able to adapt it very easily if you are trying to do something differently.

In the example provided on datatables.net, they do it with the search fields in the footer (which I personally dislike), so my example is with them in the header. For starters, you will need two rows in your <thead> -- make sure your filter row is the first row, and your actual headers is the second row

Working DEMO

<table class="table">
  <thead>
    <tr class="filter-row">
      <th class="actions">
      </th>
      <th class="searchable datatables-dropdown">
        <select name="FormName">
          <option>Form1</option>
          <option>Form2</option>
        </select>
      </th>
      <th class="display-order">
      </th>
      <th class="searchable">
        Label Text
      </th>
      <th class="searchable">
        View Roles
      </th>
      <th class="searchable">
        Edit Roles
      </th>
      <th class="searchable">
        Delete Roles
      </th>
      <th class="searchable">
        Add Roles
      </th>
      <th class="searchable">
        Field Type
      </th>
      <th class="searchable">
        Note Field
      </th>
      <th class="searchable">
        Note Required
      </th>
      <th class="searchable">
        Default
      </th>
      <th class="searchable">
        Reason List Group
      </th>
      <th class="searchable">
        Reason Required
      </th>
    </tr>
    <tr>
      <th class="actions">
        Actions
      </th>
      <th>
        Form Name
      </th>
      <th>
        Display Order
      </th>
      <th>
        Label Text
      </th>
      <th>
        View Roles
      </th>
      <th>
        Edit Roles
      </th>
      <th>
        Delete Roles
      </th>
      <th>
        Add Roles
      </th>
      <th>
        Field Type
      </th>
      <th>
        Note Field
      </th>
      <th>
        Note Required
      </th>
      <th>
        Note Default
      </th>
      <th>
        Reason List Group
      </th>
      <th>
        Reason Required
      </th>
    </tr>
  </thead>
  <tfoot>

  </tfoot>
  <tbody>

  </tbody>
</table> 

Then, in your JavaScript, you can convert your filter rows from the plain text to the <input> elements like so:

$(function () {
    // First -- Convert plain text to search field inputs
    $('.table thead tr:first th.searchable:not(.datatables-dropdown)').each(function () {
        var title = $(this).text().trim();
        $(this).css({ "padding": "5px" });
        $(this).html('<input type="text" placeholder="Search ' + title + '" style="width: 115px;" />');
    });

    // Then -- initialize DataTable
    var table = $(".table").DataTable({
        // ... Initialization options
    });

    // Lastly -- call function for wiring up the search fields to the table passed in
    ApplySearchFieldsToDatatable(table);
});

function ApplySearchFieldsToDatatable (table) {
    // https://datatables.net/examples/api/multi_filter.html
    table.columns().every(function () {
        var column = this,
        header = $(column.header()), // returns LAST <tr> in <thead>

        // we need to also grab the first <tr> in <thead> because that is where the search boxes are
        searchHeader = header.parent().prev(),

        // Get the corrisponding <th> in the first <tr> (the filter row) 
        currentColumn = searchHeader.children(":eq(" + header.index() + ")");

        // Unbind existing event listeners on old column position
        $('select', currentColumn).off("change");
        $('input', currentColumn).off("input").off("propertychange");

        // Add new event listeners for new column position
        $('select', currentColumn).on('change', function () {
            if (column.search() !== this.value) {
                column.search(this.value).draw();
            }
        });
        $('input', currentColumn).on('input propertychange', function () {
            if (column.search() !== this.value) {
                column.search(this.value).draw();
            }
        });

        // Need to set the value of the inputs/selects to the search value saved by "stateSave: true"
        // This is needed on page reload when the search state gets saved, but the inputs get redrawn 
        // from scratch. They do not inherently retain their value, so the data in the table does not
        // match the values in the search fields.
        if (column.search().length) {
            currentColumn.find('input').val(column.search());
            currentColumn.find('select').val(column.search());
        }
    });
}

Upvotes: 2

Related Questions