【问题标题】:How to do a non-text based search on a datatable when a select changes选择更改时如何对数据表进行基于非文本的搜索
【发布时间】:2022-01-11 10:42:06
【问题描述】:

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

到目前为止我已经尝试过:

LIVE DATATABLES

基本上我是这样尝试使用搜索引擎的:

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

但很明显,如果我们将字符串与“彩色方块”进行比较,则没有结果。

如果用户选择活动,我怎么做,只显示绿色方块,如果用户选择非活动,只显示红色方块?

我们将不胜感激任何帮助

【问题讨论】:

  • 看起来状态行有 CSS 类 status-activestatus-inactive,您可以使用它来获取行的状态并从那里过滤。
  • 我在想类似的东西,但我不知道怎么做,你能提供一个示例代码吗?
  • 在您的代码中,当您选择 Active 时,您会得到 <option value="System Architect">Active</option> 的值,但 System Architect 如何匹配任何行?
  • @CarstenLøvboAndersen 抱歉,我更新了代码。该值应仅为ActiveInactive。我们需要将status-activeActivestatus-inactiveInactive 匹配

标签: javascript jquery datatables


【解决方案1】:

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

$(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="stackoverflow" />
  <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>$3,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>$5,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>$3,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() 获取选择的值来选择的内容,这将为我们提供activeinactivenone(我对您的 HTML 下拉菜单进行了必要的调整以添加这些值。)

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

更新状态

如果未选择任何状态 (none),则我们通过获取具有类 .status-active.status-inactive 的每个元素来取消隐藏所有行,这是通过以下方式完成的:

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

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

过滤活动/非活动

这是实际进行过滤的代码:

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

更仔细地检查第一行,有一个ternary operator,它检查state是否等于active,如果是,它将输出inactive,反之亦然,这样做的目的是选择 opposite 类属性,以便我们可以隐藏它。

第二行简单地获取所有具有所选状态的行,并使它们可见。

【讨论】:

  • 非常感谢!我现在来测试一下。顺便说一句,最好的方法是什么?
【解决方案2】:

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

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

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

因此,在您的情况下,您可以使用彩色方块作为显示值,并使用“Active”和“Inactive”作为过滤器值。

因为您有一个预先构建的 HTML 表格,您可以使用 DataTables 支持HTML 5 正交值来提供过滤条件:

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

在上面的片段中,我将data-filter="Inactive" 属性添加到&lt;td&gt; 标记中。


还需要以下额外步骤:

因为您想将下拉过滤器与全局文本过滤器结合使用,所以您不能将它们作为两个单独的 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 的原因。

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

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

$('#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="stackoverflow" />
    <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>$3,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>$5,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>$3,120</td>
          </tr>
        </tbody>
      </table>
    </div>



  </body>
</html>

最后一点:

如果您是动态填充 HTML 表格,那么您可以使用 DataTables columns.render 函数来实现与 HTML5 data-filter 属性相同的效果。

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

【讨论】:

    猜你喜欢
    • 2011-08-24
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多