【问题标题】:jQuery DataTables filter rows based on multiple valuesjQuery DataTables 基于多个值过滤行
【发布时间】:2018-06-21 02:06:36
【问题描述】:

我正在尝试使用多个过滤器,这些过滤器将根据选择的过滤器隐藏/显示我的数据表上的行。我的计划是将过滤器值放在一个数组中,并将它们与第一列中的数据搜索属性进行比较,但我目前拥有的不起作用。

这是一个 JSfiddle,我在下面加上代码 https://jsfiddle.net/dmcgrew/06j4pxjk/3/

带有过滤器和表格数据复选框的 HTML..

<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>

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();    
   }
});

【问题讨论】:

  • 它适用于我jsfiddle.net/06j4pxjk/2
  • 不完全。当我同时选择时,我没有得到任何结果。我应该看到所有 3 行。此外,如果我同时选择两个然后取消选择 Dogs,当我应该只看到第一行时,我仍然会看到所有 3 个。
  • 您希望过滤器像or 而不是and?
  • 是的,所以如果有人选择 cat 和 dog,它将显示包含 cat 或 dog 的行。

标签: javascript jquery datatables


【解决方案1】:

您必须检查filter 的长度。

如果没有filter,则$.fn.dataTable.ext.search.push 函数必须为所有行返回true。

而且,我认为search.pop() 也应该适用于取消选中...

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

【讨论】:

    【解决方案2】:

    我使用fnFilter API 对您的代码进行了一些更改:

    文档: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);  
    }
    

    你可以在这里看到它的工作原理:JSFiddle demo

    【讨论】:

    • 这太棒了.. 但是知道为什么在准备好 dom 时这不起作用吗?
    • 没关系.. 我看到 dataTable() 和 DataTable() 之间存在差异。我将不得不对此进行一些阅读。感谢您的帮助!
    • 您知道是否有一种方法可以跨多个列进行这项工作?我在第 2 列中有一些数据,我也想过滤这些数据。
    • 您可以创建另一个更详细的问题,并在此处添加链接作为评论...我会看看 :)
    • 没问题..这里是链接:stackoverflow.com/questions/48229250/…
    【解决方案3】:

    考虑到,接受的答案是指旧接口fnFilter,并且从 DataTables 1.10 开始,建议使用新 API,我将允许自己提供更多最新的解决方案,在我看来,这种解决方案更具可扩展性、更简洁简单:

    //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>

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 2019-08-16
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多