select 更改时如何对数据表进行非文本搜索

How to do a non-text based search on a datatable when a select changes

当列的内容不是文本时,我正在尝试通过 select 过滤数据表列 status

到目前为止我尝试过的:

LIVE DATATABLES

基本上我试过这样使用搜索引擎:

$('#search2').on('change', () =>
{
    DT1.search($('#search2').val()).draw();
});

但很明显,如果我们将字符串与 'colored square' 进行比较,则没有结果。

如果用户 select 活跃,只显示绿色方块,如果用户 select 不活跃,只显示红色方块?

任何帮助将不胜感激

这不是我在深夜匆忙写作的最佳方式,但我想我会提供一个可行的解决方案,以防其他人没有这样做。

$(document).ready(function() {
  var DT1 = $('#example').DataTable({
    columnDefs: [{
      orderable: false,
      className: 'select-checkbox',
      targets: 0,
    }],
    select: {
      style: 'os',
      selector: 'td:first-child'
    },
    order: [
      [1, 'asc']
    ],
    dom: 'lrt'
  });
  $(".selectAll").on("click", function(e) {
    if ($(this).is(":checked")) {
      DT1.rows().select();
    } else {
      DT1.rows().deselect();
    }
  });

  $('#search').on('input', () => {
    DT1.search($('#search').val()).draw();
  });
  $('#search2').on('change', () => {
    const state = $("#search2").val();
    if (state === "none") {
      $(".status-active").parent().parent().attr("hidden", false);
      $(".status-inactive").parent().parent().attr("hidden", false);
      return;
    }

    $(".status-" + ((state === "active") ? 'inactive' : 'active')).parent().parent().attr("hidden", true);
    $(".status-" + state).parent().parent().attr("hidden", false);

  });
});
body {
  font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
  color: #333;
  background-color: #fff;
}

.status-active {
  height: 25px;
  width: 25px;
  background-color: #385C0B;
  margin: 0 auto;
}

.status-inactive {
  height: 25px;
  width: 25px;
  background-color: #CC000C;
  margin: 0 auto;
}
<!DOCTYPE html>
<html>

<head>
  <meta name="description" content="Whosebug" />
  <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

  <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
  <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
  <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css">

  <meta charset=utf-8 />
  <title>DataTables - JS Bin</title>
</head>

<body>


  <div class="container">
    <div class="row">
      <div class="form-inline">
        <input id="search" title="Search" placeholder="Search" class="filter-input form-control form-control-sm m-2" type="text" name="filter-project" value="">
        <select id="search2" name="expense_category" class="form-control form-control-sm m-2">
          <option value="none">Select a Status</option>
          <option value="active">Active</option>
          <option value="inactive">Inactive</option>
        </select>
      </div>
      <table id="example" class="display nowrap" width="100%">
        <thead>
          <tr>
            <th class="text-center"><input type="checkbox" class="selectAll" name="selectAll" value="all"></th>
            <th>Name</th>
            <th>Status</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td></td>
            <td>Tiger Nixon</td>
            <td>
              <div class="status-active" title="Active"></div>
            </td>
            <td>Edinburgh</td>
            <td>61</td>
            <td>2011/04/25</td>
            <td>,120</td>
          </tr>
          <tr>
            <td></td>
            <td>Garrett Winters</td>
            <td>
              <div class="status-active" title="Active"></div>
            </td>
            <td>Edinburgh</td>
            <td>63</td>
            <td>2011/07/25</td>
            <td>,300</td>
          </tr>
          <tr>
            <td></td>
            <td>Donna Snider</td>
            <td>
              <div class="status-inactive"></div>
            </td>
            <td>New York</td>
            <td>27</td>
            <td>2011/01/25</td>
            <td>,120</td>
          </tr>
        </tbody>
      </table>
    </div>
</body>

</html>

说明

我们主要关注状态下拉列表更改时的事件处理程序。

$('#search2').on('change', () =>
{
    const state = $("#search2").val();
    if (state === "none") {
      $(".status-active").parent().parent().attr("hidden", false);
      $(".status-inactive").parent().parent().attr("hidden", false);
      return;
    }

    $(".status-" + ((state === "active") ? 'inactive' : 'active')).parent().parent().attr("hidden", true);
    $(".status-" + state).parent().parent().attr("hidden", false);
    
});

首先,我们通过使用 .val() 获取 selection 的值来获取下拉菜单的状态以及 select 的内容,这将给我们 activeinactivenone(我对您的 HTML 下拉菜单进行了必要的调整以添加这些值。)

有了这些信息,我们就知道需要进行什么类型的过滤了。

更新状态

如果没有 selected (none) 状态,那么我们通过使用 classes .status-active.status-inactive 获取每个元素来取消隐藏所有行,这是通过以下方式完成的:

$(".status-active").parent().parent().attr("hidden", false);

$(".status-active") 获取具有活动 class 的所有行,并获取为我们提供行元素本身的父项的父项,并将 hidden 属性设置为 false,使其可见。

过滤Active/Inactive

下面是实际进行过滤的代码:

$(".status-" + ((state === "active") ? 'inactive' : 'active')).parent().parent().attr("hidden", true);
$(".status-" + state).parent().parent().attr("hidden", false);

仔细检查第一行,有一个 ternary operator 检查 state 是否等于 active,如果是,它将输出inactive,反之亦然,这样做的目的是 select 相反 class 属性,因此我们可以隐藏它。

第二行只是获取状态为 select 的所有行,并使它们可见。

您可以使用 orthogonal data 的数据表支持。此功能允许您为 table 中的每个单元格保存多个值,包括:

  • 显示值
  • 排序时使用的值
  • 过滤时使用的值

(大多数时候,您没有明确使用此功能,因此所有这些值都与显示值相同。)

因此,在您的情况下,您可以使用彩色方块作为显示值,使用“有效”和“无效”这两个词作为筛选值。

因为你有一个预建的 HTML table,你可以使用 DataTables 对 HTML 5 正交值的支持来提供过滤条件:

<td data-filter="Inactive"><div class="status-inactive"></div></td>

在上面的片段中,我将 data-filter="Inactive" 属性添加到 <td> 标签。


还需要以下额外步骤:

因为您想将下拉过滤器与全局文本过滤器组合在一起,所以您不能将它们作为两个单独的 DT1.search() 函数提供。目前,这两个功能无法正确组合使用。

要解决这个问题,您可以为下拉过滤器创建自定义搜索功能:

$.fn.dataTable.ext.search.push(
  function( settings, searchData, index, rowData, counter ) {
    console.log( searchData );
    var statusFilter = $('#search2').val();
    var statusCell =  searchData[2] || ''; // using 'status' data from the 3rd column
    return (statusFilter === '' || statusFilter === statusCell) ;
  }
);

这个自定义搜索函数被添加到一个数组中,该数组包含 DataTables 提供的开箱即用的现有搜索函数 - 这就是我们在上面的代码片段中使用 $.fn.dataTable.ext.search.push 的原因。

现有的搜索功能与我们自定义的下拉搜索功能相结合。

我们还将相关事件更改为简单地重新绘制 table - 这将自动导致执行搜索函数数组:

$('#search2').on('change', () => {
  DT1.draw();
});

这是一个演示:

    $(document).ready(function() {
    
    $.fn.dataTable.ext.search.push(
      function( settings, searchData, index, rowData, counter ) {
        //console.log( searchData );
        var statusFilter = $('#search2').val();
        var statusCell =  searchData[2] || ''; // using 'status' data from the 3rd column
        return (statusFilter === '' || statusFilter === statusCell) ;
      }
    );
    
        var  DT1 = $('#example').DataTable(
        {
            columnDefs: [ 
            {
                orderable: false,
                className: 'select-checkbox',
                targets:   0,
            } ],
            select: {
                style:    'os',
                selector: 'td:first-child'
            },
            order: [[ 1, 'asc' ]],
            dom: 'lrt'
        });

        $(".selectAll").on( "click", function(e) {
            if ($(this).is( ":checked" )) {
                DT1.rows(  ).select();        
            } else {
                DT1.rows(  ).deselect(); 
            }
        });
      
        $('#search').on('input', () => {
            DT1.search($('#search').val()).draw();
        });
        
        $('#search2').on('change', () => {
            DT1.draw();
        });
        
    });
<!DOCTYPE html>
<html>
  <head>
<meta name="description" content="Whosebug" />
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

    <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
    <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/select/1.3.3/js/dataTables.select.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.3.3/css/select.dataTables.min.css">
    
    <meta charset=utf-8 />
    <title>demo</title>

<style>
body {
  font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
  margin: 0;
  padding: 0;
  color: #333;
  background-color: #fff;
}

.status-active{
    height: 25px;
    width: 25px;
    background-color: #385C0B;
    margin: 0 auto;
}

.status-inactive{
    height: 25px;
    width: 25px;
    background-color: #CC000C;
</style>
  </head>
  <body>
    
    
    <div class="container">
            <div class="row">
        <div class="form-inline">
            <input id="search" title="Search" placeholder="Search" class="filter-input form-control form-control-sm m-2"
                type="text" name="filter-project" value="">
            <select id="search2" name="expense_category" class="form-control form-control-sm m-2">
                <option value="">Select a Status</option>
                <option value="Active">Active</option>
                <option value="Inactive">Inactive</option>
            </select>
        </div>
      <table id="example" class="display nowrap" width="100%">
        <thead>
          <tr>
            <th class="text-center"><input type="checkbox" class="selectAll" name="selectAll" value="all"></th>
            <th>Name</th>
            <th>Status</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td></td>
            <td>Tiger Nixon</td>
            <td data-filter="Active"><div class="status-active" title="Active"></div></td>
            <td>Edinburgh</td>
            <td>61</td>
            <td>2011/04/25</td>
            <td>,120</td>
          </tr>
          <tr>
            <td></td>
            <td>Garrett Winters</td>
            <td data-filter="Active"><div class="status-active" title="Active"></div></td>
            <td>Edinburgh</td>
            <td>63</td>
            <td>2011/07/25</td>
            <td>,300</td>
          </tr>
          <tr>
            <td></td>
            <td>Donna Snider</td>
            <td data-filter="Inactive"><div class="status-inactive"></div></td>
            <td>New York</td>
            <td>27</td>
            <td>2011/01/25</td>
            <td>,120</td>
          </tr>
        </tbody>
      </table>
    </div>



  </body>
</html>


终点:

如果要动态填充 HTML table,则可以使用 DataTables columns.render 函数实现与 HTML5 [=20] 相同的效果=] 属性.

在你的情况下你不需要这个,因为你的 HTML table 是在你创建 DataTable 之前预先构建的。