web-dev-qa-db-ja.com

DataTablesは子行のコンテンツを検索します

DataTables検索バーでは、 子行 内のコンテンツを検索できません。

私はこれに対する答えを見つけるために広範囲に検索しました( 12 、、 456789 )、しかし応答はほとんどまたはまったくありませんこの問題について。

これは単純な jsfiddle および DataTablesデバッガーの結果 です。

テーブルで拡張番号(子行にあります)を検索したいのですが、検索バーに拡張番号の1つを入力しても、検索結果が表示されません。

私はこれを追加することによって この投稿 から解決策を試しました:

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 でわかるように、それでも機能しません。

誰かが私を助けてくれますか?

ありがとう

11
cooltoast

質問する必要があります:子行が表示されている場合にのみ動的に挿入している子行コンテンツを検索できると思われる理由は何ですか?そして、column()検索で他の行のコンテンツをどのようにカバーできるでしょうか。

そうは言っても、もちろん回避策があります。子行のコンテンツを何度も作成する代わりに、配列に保持します。

_var details = [];
_

これで、テーブルを初期化するときに、子行のコンテンツも初期化します。

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

Format()関数で、簡単にアクセスできるように[内線番号]フィールドにクラスを追加します。

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

子行を表示するときは、format()を呼び出す代わりに、_details[]_から事前にレンダリングされたコンテンツを挿入します。

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

2
davidkonrad

これはかなり古いスレッドであり、受け入れられた答えは機能しますが、別の解決策を提案したかったのです。

同じ問題が子行内で検索できないという問題がありました。私の解決策は、子行のデータを含むテーブルの最後に非表示の<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;
}

テーブルの最後に、子行のすべてを含む<td>が1つ残っていますが、これは非表示であり、検索ボックス/フィルターで機能します。

1
Brian Powell

1つの列に拡張機能のリストがある場合は、次のようにそれらを分割する必要があります。

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

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