jQuery DataTables filter rows based on multiple values

不羁岁月 提交于 2019-12-24 15:53:22

问题


I am trying to have multiple filters that will hide/show rows on my datatable based on which filters are selected. My plan is to place the filter values in an array and compare those to the data-search attribute in the first column, but what I currently have does not work.

Here's a JSfiddle that I have plus code below https://jsfiddle.net/dmcgrew/06j4pxjk/3/

HTML with checkboxes for filters and the table data..

<label>
    <input type="checkbox" name="cat" value="cat" class="filter"> Cats
</label>

<label>
    <input type="checkbox" name="dog" value="dog" class="filter"> Dogs
</label>

<table class="select_items">
    <thead>
        <tr>
            <th>Item</th>
            <th>Description</th>
            <th>Crest Allowed</th>
            <th>&nbsp;</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-search="cat">1</td>
            <td>Testing Bowl</td>
            <td>NO</td>
            <td><button class="button">Select</button></td>
        </tr>
        <tr>
            <td data-search="dog">32</td>
            <td>Cup Test</td>
            <td>NO</td>
            <td><button class="button">Select</button></td>
        </tr>
        <tr>
            <td data-search="dog">3335</td>
            <td>Bowl Test</td>
            <td>NO</td>
            <td><button class="button">Select</button></td>
        </tr>

    </tbody>
</table>

The JS..

var select_items = $('.select_items').DataTable();

var filters = [];

$('input.filter').on('change', function(){
   var filters = [];
   $("input.filter:checked").each(function(){

    var checkedBox = $(this).val();
    if (filters.indexOf(checkedBox) === -1){
        filters.push(checkedBox);
    }
   });

   console.log(filters);

   if(this.checked){
      $.fn.dataTable.ext.search.push(
         function (settings, data, dataIndex){
            return (data[0].indexOf(filters) > -1) ? true : false;
         }
      );
   } 

   select_items.draw();

   if(this.checked){
      $.fn.dataTable.ext.search.pop();    
   }
});

回答1:


I made a few changes in your code, using the fnFilter API:

Documentation: https://datatables.net/docs/DataTables/1.9.0/DataTable.html#fnFilter

$(function() {
  otable = $('.select_items').dataTable();
})

function filterme() {
  //build a regex filter string with an or(|) condition
  var types = $('input:checkbox[name="filter"]:checked').map(function() {
    return '^' + this.value + '\$';
  }).get().join('|');
  //filter in column 0, with an regex, no smart filtering, no inputbox,not case sensitive
  otable.fnFilter(types, 0, true, false, false, false);  
}

You can see it working here: JSFiddle demo




回答2:


You have to check for the filter length.

If there is no filter, the $.fn.dataTable.ext.search.push function has to return true for ALL rows.

And, I think that search.pop() should apply on uncheck too...

var select_items = $('.select_items').DataTable();


$('input.filter').on('change', function(){
  var filters = [];
  $("input.filter:checked").each(function(){
    var checkedBox = $(this).val();
    if (filters.indexOf(checkedBox) === -1){
      filters.push(checkedBox);
    }
  });

  console.log(filters.length);

  $.fn.dataTable.ext.search.push(function(settings, data, dataIndex){
    if(filters.length>0){
      return (data[0].indexOf(filters) > -1) ? true : false;
    }else{
      return true;
    }
  });

  select_items.draw();
  $.fn.dataTable.ext.search.pop();
});

Updated Fiddle




回答3:


Considering, accepted answer refers to legacy interface fnFilter and, as of DataTables 1.10 new API is suggested, I'll allow myself to provide more up to date solution, which is, in my opinion, way more scalable, neat and simple:

//define statical data
var srcData = [
  {search: 'Cat', item: '1', descr: 'Testing Bowl', crest: 'NO'},
  {search: 'Dog', item: '32', descr: 'Cup Test', crest: 'NO'},
  {search: 'Dog', item: '3335', descr: 'Bowl Test', crest: 'NO'},
];
//define dataTable object
var dataTable = $('#mytable').DataTable({
  sDom: 't',
  data: srcData,
  columns: [
    {title: 'Item', data: 'item'},
    {title: 'Description', data: 'descr'},
    {title: 'Crest Allowed', data: 'crest'},
  ]
});
//put in place dynamically created checkboxes
var searchValues = [];
dataTable.data().sort().toArray().forEach(row => {
  if(searchValues.indexOf(row.search)==-1) searchValues.push(row.search);
});
var checkboxes = searchValues.reduce((html, item) => html += `<input type="checkbox" value="${item}" class="filter">${item}</input>`,'');
$(checkboxes).insertBefore($('#mytable'));
//employ $.fn.DataTable.ext.search
var lookupValues = [];
$.fn.DataTable.ext.search.push((settings, row, index, rowObj) => lookupValues.indexOf(rowObj.search) > -1 || lookupValues.length == 0);
//watch checkboxes and redraw table on change accordingly
$(".filter").on('change', () => {
  lookupValues = [...$('.filter:checked')].map(checkbox => $(checkbox).val());
  dataTable.draw();
});
<!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <table id="mytable"></table>
</body>
</html>


来源:https://stackoverflow.com/questions/48212233/jquery-datatables-filter-rows-based-on-multiple-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!