DataTables 搜索子行内容

Posted

技术标签:

【中文标题】DataTables 搜索子行内容【英文标题】:DataTables search child row content 【发布时间】:2015-08-08 20:49:22 【问题描述】:

在数据表搜索栏不会让我中搜索内容child rows。 P>

我已搜查广泛找到这个问题的答案(1,2,3,4,5,6,7,8,9) ,但有一点在这个问题上没有任何反应。

下面是一个简单的jsfiddle和DataTables debugger results P>

我想在表格中搜索一个分机号码(这是子行中),但该分机号码在搜索栏中叶打字一个没有搜索结果。 P>

我试图从@ 987654333溶液@,通过添加这样的:

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

...但它仍然无法正常工作,因为你可以在@ 987654334看@。

有人可以帮帮我吗?

谢谢

【问题讨论】:

【参考方案1】:

解决方案

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

例如,您可以使用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,即使数据只出现在子行中,也会显示第一行。

【讨论】:

从我所见的情况来看,这是一个更好的解决方案,并且不需要任何额外的代码。干净简单。感谢分享! 这真的很有用,但是当搜索的数据只出现在孩子中时,我怎么能显示子行以及父行?如果搜索到的数据仅出现在父级中,则子级应保持隐藏状态,并且仅显示父级。【参考方案2】:

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

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

var details = [];

现在,当您初始化表格时,您也会初始化子行内容:

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

在 format() 函数中,为 Extension Number 字段添加一个类以便于访问:

'<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');

创建一个过滤器,该过滤器仅返回具有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);
    );
);

分叉小提琴 -> https://jsfiddle.net/7o67vhrz/


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

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

又一个分叉的小提琴 -> https://jsfiddle.net/ds3qp41g/


最后一个例子。结合细节搜索和“原生”搜索

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

小提琴 -> https://jsfiddle.net/h2u4fowj/

【讨论】:

感谢您的回复!我可能没有正确表达我的问题:有什么方法可以将此自定义过滤器功能添加到右上角的 DataTables 全局搜索栏中?我只需要像this link 那样设置 $.fn.dataTable.ext.search.push() 方法吗? 嘿@cooltoast,过滤器在全球范围内一直有效 - 这就是为什么我最后 pop() 它。我不完全确定您要问什么,您是否希望将搜索输入一般附加到上述过滤器功能? 在您的 jsfiddle 中,如果您在右上角的搜索栏中搜索“1562”,则不会显示任何内容(但它确实适用于底部的各个列搜索栏)。由于我的实际应用程序没有那些列搜索栏,我想将自定义过滤器功能附加到右上角的搜索栏。这可以通过 DataTables API 完成吗? 嗯,现在我似乎无法搜索名称或除分机号码之外的任何内容(尝试搜索“Tiger”)。是否可以保留原来的搜索栏功能并添加过滤功能来搜索分机号码? (再一次,很抱歉没有正确解释我的问题) @cooltoast,你很难满足 :) 这应该是一个聪明的人,但无论如何都做了一个例子和一个小提琴。我的最后一次编辑。【参考方案3】:

这是一个相当古老的线程,并且接受的答案确实有效,但我想提出一个替代解决方案。

我遇到了同样的问题,无法在子行中搜索,我的解决方案是在包含子行中数据的表末尾创建一个隐藏的&lt;td&gt; - 这样,索引器会看到它,但用户没有。

对于有限的 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;

您在表格末尾留下一个 &lt;td&gt;,其中包含子行中的所有内容,但它是不可见的,并且它适用于搜索框/过滤器。

【讨论】:

我想我最终不得不这样做,但我想避免这种情况,因为它会为我的表创建臃肿的 ajax 调用。我的子行(而不是行)的问题是该行是一个 html 表,并且该表中的字段是我想要搜索的,因此在主列中包含该表只会很烦人。我会看看我能做些什么,尽管可能会有所改进。 这也是我的场景 - 我有一个子行,它只包含一个巨大的 html 表,填充了我在“标题”行中不想要的其他 json 记录(用户点击)。我发现返回额外隐藏行所花费的时间对我来说并不是一个障碍 - 如果它适合你,也许接受的答案就是解决方案? 可能我昨天那个时候几乎完成了工作,所以没有采取任何进一步的措施,考虑到它我会将我的子行字段从表转换为 json 本身中的对象并循环通过该对象动态生成一个子表。我会告诉你我的进展情况,当我完成后,我将处理 1000 多行,所以我能做的任何事情来最小化 ajax 数据都会有所帮助。【参考方案4】:

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

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

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

【讨论】:

以上是关于DataTables 搜索子行内容的主要内容,如果未能解决你的问题,请参考以下文章

休眠搜索子实体

NSPredicate 根据父实体的属性搜索子实体实例

EWS 搜索子字符串的约会正文

sql MSSQL搜索子字符串

Gcloud 日志查看器 - 搜索子字符串过滤器不起作用

搜索子字符串的数组元素并返回索引