首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jquery数据可定制列搜索

Jquery数据可定制列搜索
EN

Stack Overflow用户
提问于 2021-04-14 10:07:48
回答 1查看 3.5K关注 0票数 3

我已经对此进行了一段时间的研究,而有用的信息在没有解决方案的情况下正在枯竭。

我使用的是数据表,在某些列中,我将显示一个选中的多选中框,允许用户通过继续进行选择来编辑他们的数据。

我得到了使用initComplete的每列搜索框,它们确实过滤列中的数据,但不是以可接受的方式;它们匹配选项的文本,但也匹配select元素的类,甚至对所有未选择的选项都是无用的。

代码语言:javascript
复制
...,
initComplete: function () {
            // Apply the search
            this.api().columns().every(function () {
                var that = this;

                $('input', this.footer()).on('keyup change clear', function () {
                    if (that.search() !== this.value) {
                        that
                            .search(this.value)
                            .draw();
                    }
                });
            });
        }

我希望这只匹配选定选项的文本的选择框。编写函数以获取给定行中的选择框的文本字符串数组是我很容易完成的工作,但我很难找到这样一个自定义函数可以连接到Datatable流的位置。

Datatables文档提到您可以为正交数据定义列过滤器函数,但是没有给出这方面的示例,我也很难在网上找到任何这样的函数。我试图在DataTable初始化中添加以下内容,但没有调用:

代码语言:javascript
复制
...,
"columns": [          
            {
                filter: function (a,b,c) {
                    console.log('called from column filter');
                    console.log(arguments)
                    return false;
                }
            },
            {
                filter: function (a,b,c) {
                    console.log('called to column filter');
                    console.log(arguments)                 
                    return false;
                }
            },
            null  
        ]

谢谢您抽时间见我。

更新

所以我发现我可以把一个函数推到$.fn.dataTable.ext.search.push上(.)它似乎能满足我的需要。沿着这条路径,我发现在参数中传递的列html不包括我需要的所选的生成元素,而是预选的.我尝试过使用table.rows.invalidate.draw,但这只是从DOM中移除选定的元素,而不是通过在预期的html数据中传递数据来解决这个问题。

我希望传入的实际行html示例:

代码语言:javascript
复制
<td>
<select class="myclasses form-control" multiple="" style="display: none;">                    
    <option value="...">Bahamas</option>
    ...
</select>
<div class="chosen-container chosen-container-multi" title="" style="width: 437px;">
    <ul class="chosen-choices">
        <li class="search-choice">
            <span>Greece</span>
            <a class="search-choice-close" data-option-array-index="4"></a>
        </li>
        <li class="search-choice">
            <span>Belgium</span>
            <a class="search-choice-close" data-option-array-index="6"></a>
        </li>
        <li class="search-choice">
            <span>France</span>
            <a class="search-choice-close" data-option-array-index="7"></a></li><li class="search-field">
            <input class="chosen-search-input" type="text" autocomplete="off" value="Select some options" style="width: 25px;">
        </li>
    </ul>
    <div class="chosen-drop">
      <ul class="chosen-results"></ul>
    </div>
</div>
</td>

搜索调用中的实际参数数据,该数据似乎处于预选状态。这就是为什么我期望.invalidate()修复这个.

代码语言:javascript
复制
<select class="myclasses form-control" multiple>                    
    <option value="...">Bahamas</option>
</select>

在将select html添加到表中之前,我现在正在研究生成所选的html。如果用户在将选择框选项添加到表后对其进行更改,这可能仍然存在问题,但我将在到达时查看。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-14 17:35:13

我认为使用$.fn.dataTable.ext.search的方法是正确的,因为与search() API函数不同,它提供了访问DOM的能力,在这里可以找到用户选择(即在DataTables对象之外)。

但是,由于$.fn.dataTable.ext.search不仅限于一个列,还需要做一些额外的工作,以确保跨不同列的组合搜索仍能正常工作。

这是一个有点基本的例子,但它展示了一种方法。

每个input事件所做的唯一事情就是触发一个表重新绘制。这种重新绘制反过来触发了全局搜索功能:

代码语言:javascript
复制
    initComplete: function () {
      var api = this.api();
      api.columns().each(function () {
        $('input', this.footer()).on('keyup change clear', function () {
          api.draw();
        });
      });
    }

搜索函数如下所示。代码可以简化--但它展示了基本的方法:

代码语言:javascript
复制
  $.fn.dataTable.ext.search.push(
    function( settings, searchData, index, rowData, counter ) { 

      var fromFilter = $( '#in_0' ).val();
      var toFilter = $( '#in_1' ).val();

      var trNode = table.row( [index] ).node();

      var fromTdNode = $( "td:nth-child(1)", trNode );
      var fromSelectedValNodes = $( "select option:selected", fromTdNode );   
      var fromSelections = '';
      fromSelectedValNodes.each(function() {
        fromSelections += ( $( this ).val() + ', ' ); 
      });

      var toTdNode = $( "td:nth-child(2)", trNode );
      var toSelectedValNodes = $( "select option:selected", toTdNode );   
      var toSelections = '';
      toSelectedValNodes.each(function() {
        toSelections += ( $( this ).val() + ', ' ); 
      });
      
      if ( fromSelections.trim().toLowerCase().includes( fromFilter.trim().toLowerCase() ) &&
              toSelections.trim().toLowerCase().includes( toFilter.trim().toLowerCase() ) ) {
        return true;
      } else {
          return false;
      }
    }
  );

我们检索用户提供的两个搜索值,并将它们保存在fromFiltertoFilter中。

然后,对于包含多选择的两列中的每一列,我们将检索所选值的文本。我们使用DataTables API从每个DataTables行获取相关的node()对象。

然后使用jQuery选择器将所选的多选择值收集到一个字符串中。

最后,我们将看到搜索项是否包含在我们构建的字符串中。我们对这两列中的每一列分别这样做,这样就可以一致地过滤整个表。

这个实现假设只有两个列包含这些选择的多个选择,而且它们也是前两个列。

我还使用DataTable选项从dom中删除默认的全局搜索输入框,因为这也会导致调用$.fn.dataTable.ext.search

最后注意:我为我的小型演示加载数据的方式似乎与您的数据加载方式不同--因此,如果需要更改,以下是我的完整独立演示:

代码语言:javascript
复制
<!doctype html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
  <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">

  <!-- chosen select library -->
  <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.min.css">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.min.js"></script>


</head>

<body>

<div style="margin: 20px;">

    <table id="example" class="display dataTable cell-border" style="width:100%">
        <thead>
            <tr>
                <th>From Country</th><th>To Country</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td></td><td></td>
            </tr>
            <tr>
                <td></td><td></td>
            </tr>
            <tr>
                <td></td><td></td>
            </tr>
            <tr>
                <td></td><td></td>
            </tr>
            <tr>
                <td></td><td></td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th></th><th></th>
            </tr>
        </tfoot>
    </table>

</div>

<script>

$(document).ready(function() {

  $('#example tfoot th').each( function ( idx ) {
    var title = $(this).text();
    $(this).html( '<input id="in_' + idx + '" type="text" placeholder="Search ' + title + '"/>' );
  } );

  var table = $('#example').DataTable( {

    dom: 'lrtip', // removed "f" for "filter".

    columnDefs: [
      {
        targets: [ 0, 1 ],
        render: function ( data, type, row ) {
          var select = $('<select multiple class="chosen-select"><option value=""></option></select>');
          select.append( '<option value="Argentina">Argentina</option>' );
          select.append( '<option value="Brazil">Brazil</option>' );
          select.append( '<option value="Cuba">Cuba</option>' );
          select.append( '<option value="Denmark">Denmark</option>' );
          select.append( '<option value="Egypt">Egypt</option>' );
          return select[0].outerHTML;
        }        
      }
    ],

    initComplete: function () {
      var api = this.api();
      api.columns().each(function () {
        $('input', this.footer()).on('keyup change clear', function () {
          api.draw();
        });
      });
    }
  } );

  $.fn.dataTable.ext.search.push(
    function( settings, searchData, index, rowData, counter ) { 

      var fromFilter = $( '#in_0' ).val();
      var toFilter = $( '#in_1' ).val();

      var trNode = table.row( [index] ).node();

      var fromTdNode = $( "td:nth-child(1)", trNode );
      var fromSelectedValNodes = $( "select option:selected", fromTdNode );   
      var fromSelections = '';
      fromSelectedValNodes.each(function() {
        fromSelections += ( $( this ).val() + ', ' ); 
      });

      var toTdNode = $( "td:nth-child(2)", trNode );
      var toSelectedValNodes = $( "select option:selected", toTdNode );   
      var toSelections = '';
      toSelectedValNodes.each(function() {
        toSelections += ( $( this ).val() + ', ' ); 
      });
      
      if ( fromSelections.trim().toLowerCase().includes( fromFilter.trim().toLowerCase() ) &&
              toSelections.trim().toLowerCase().includes( toFilter.trim().toLowerCase() ) ) {
        return true;
      } else {
          return false;
      }
    }
  );

  $(".chosen-select").chosen({
    width: "75%"
  });


} );

</script>

</body>
</html>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67089676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档