DataTables 搜索子行内容

DataTables search child row content

DataTables 搜索栏不允许我搜索 child rows 内的内容。

我进行了广泛的搜索以找到此问题的答案 (1, 2, 3, 4, 5, 6, 7, 8, 9),但几乎没有关于此问题的回复。

这是一个简单的 jsfiddle and DataTables debugger results

我想在 table 中搜索一个分机号码(在子行中),但是在搜索栏中输入其中一个分机号码没有搜索结果。

我尝试了 this post 的解决方案,方法是添加:

table.columns().every( function () {
    var that = this;
    var header = this.header();

    $( 'input', this.footer() ).on( 'keyup change', function () {
        that
        .column( header.getAttribute('data-search-index')*1 ) // *1 to make it a number
        .search( this.value )
        .draw();
    } );
} );

...但它仍然不起作用,正如您在 jsfiddle linked above 中看到的那样。

有人可以帮我吗?

谢谢

我不得不问:是什么让您相信只有在显示子行时才可以在动态注入的子行内容中进行搜索? column() 搜索应该如何覆盖其他行的内容?

说到这里,当然有一个解决方法。与其一遍又一遍地创建子行内容,不如将其保存在一个数组中:

var details = [];

现在,当您初始化 table 时,您也初始化了子行内容:

...
columns: [{
   className: 'details-control',
   orderable: false,
   data: null,
   defaultContent: '',
   render: function(data, type, row, meta) {  
      details[meta.row] = format(data);
   }    
}, 
...

在 format() 函数中,在分机号码字段中添加一个 class 以便于访问:

'<td class="extNo">' + d.extn + '</td>' +

显示子行时,插入来自 details[] 的预呈现内容,而不是调用 format() :

if (row.child.isShown()) {
   row.child.hide();
   tr.removeClass('shown');
} else {
   row.child(details[row.index()]).show();            
   tr.addClass('shown');
}

创建一个过滤器,returns 仅包含 details[] 子行持有特定分机号码的行:

function filterByDetailsExtNo(extNo) {
    $.fn.dataTable.ext.search.push(
    function(settings, data, dataIndex) {
       return $(details[dataIndex]).find('.extNo').text() == extNo;
    }    
  )
  table.draw();
  $.fn.dataTable.ext.search.pop();
}  

在您的输入处理程序中使用自定义过滤器而不是 column() 搜索:

table.columns().every( function () {
    $( 'input', this.footer() ).on( 'keyup change', function () {
        filterByDetailsExtNo(this.value);
    });
});

分叉 fiddle -> https://jsfiddle.net/7o67vhrz/


更新。将上述过滤器应用于通用搜索框:

$('.dataTables_filter input')
   .off()
   .on('keyup', function() {
      filterByDetailsExtNo(this.value);
   });    

又一个分支 fiddle -> https://jsfiddle.net/ds3qp41g/


最后一个例子。结合详情搜索和 "native" 搜索

function filterByDetailsExtNoAndInput(term) {
      $.fn.dataTable.ext.search.push(
        function(settings, data, dataIndex) {
            if ($(details[dataIndex]).find('.extNo').text() == term) return true;
            for (var i=0;i<data.length;i++) {
                if (data[i].toLowerCase().indexOf(term.toLowerCase())>=0) {
                    return true
                }    
            }   
            return false;
        }    
      )
      table.draw();
      $.fn.dataTable.ext.search.pop();
    }  

fiddle -> https://jsfiddle.net/h2u4fowj/

这是一个很老的帖子,接受的答案确实有效,但我想提出一个替代解决方案。

我遇到了同样的问题,无法在子行中搜索,我的解决方案是在 table 的末尾创建一个隐藏的 <td>,其中包含子行中的数据行 - 这样,索引器可以看到它,但用户看不到。

有限的HTML,我新增了一个专栏:

<th class="hidden">Data</th>

然后,在 DataTables 中调用:

//Within var table = $('#table').DataTable( {....
columns : [
        //{ className : 'details-control'},
        { data : 'a' }, //a-e are the columns I want the user to see.
        { data : 'b' },
        { data : 'c' },
        { data : 'd' },
        { data : 'e' },            
        // this last one is my "index helper"
        { data : 'comments',
          render : function(data, type, full, meta) {
            return full.f + full.g + full.h + full.i;
          }
         }
    ],

那你只需要隐藏这个栏目。您可以通过 DataTables 推荐的方法执行此操作:

https://datatables.net/examples/basic_init/hidden_columns.html

或者通过我选择的方法:

"createdRow" : function (row,data,index) {
    $('td',row).eq(6).addClass('hidden');
}

//and the css...
.hidden {
 visibility: hidden;
}

你在 table 的末尾留下了一个 <td>,它包含子行的所有内容,但它是不可见的,并且它与搜索 box/filter thingy 一起工作.

解决方案

为了让 jQuery DataTables 搜索子行,您需要将显示在子行中的数据作为隐藏列添加到主 table 中。

例如,您可以使用 columns.visible 选项为 extn 数据 属性 添加隐藏列,如下所示:

JavaScript:

    "columns": [
        {
            "class":          'details-control',
            "orderable":      false,
            "data":           null,
            "defaultContent": ''
        },
        { "data": "name" },
        { "data": "position" },
        { "data": "office" },
        { "data": "salary" },
        { "data": "extn", "visible": false }            
    ],

HTML:

<thead>
    <tr>
        <th></th>
        <th>Name</th>
        <th>Position</th>
        <th>Office</th>
        <th>Salary</th>
        <th>Extn.</th>
    </tr>
</thead>

演示

有关代码和演示,请参阅 this jsFiddle。搜索 5407,即使数据仅出现在子行中,也会显示第一行。

如果您在一列中有一个扩展名列表,那么您会希望像这样拆分它们。

              {"data": "extn", "visible": false,
               "render": function (data, type, row, meta) {

                        var htmlDetail = '';                            
                        yourList.forEach(function (item) {
                            htmlDetail += item.extn + '|';
                        });
                        return type === 'display' ? htmlDetail : htmlDetail;
              }