JQuery Datatables在输入和选择中搜索

时间:2015-01-09 01:28:55

标签: javascript jquery datatables

将Jquery数据表与输入和选择一起使用,如下所示:http://datatables.net/examples/api/form.html 或者如果我使用自定义列渲染处理程序来生成输入并选择如何使全局表搜索工作?

如果您查看该示例,您会注意到搜索中仅包含第一列(只读一列),我该怎么做才能在搜索中包含其他列?

如果您在我的问题的链接中查看示例并在搜索中键入“Tokyo”,则返回所有行。这是因为“东京”是所有下拉菜单中的一个选项。我想只选择显示东京的行。如果输入“33”,即使第一行的第一行值为“33”,也看不到任何行。

我似乎找不到任何关于如何定义数据表中特定单元格的搜索值的文档。

5 个答案:

答案 0 :(得分:20)

记录不完善。并且它似乎在(子)版本之间以不同的方式工作,或者根本不工作。我认为dataTables旨在自动检测HTML列,但出于某种原因,大多数情况下,它不会。最安全的方法是创建自己的搜索过滤器:

$.fn.dataTableExt.ofnSearch['html-input'] = function(value) {
    return $(value).val();
};

这将在<input>上返回值<33的 33 ,并在选择了东京的<select>上返回东京。然后定义类型为html-input;

的所需列
var table = $("#example").DataTable({
    columnDefs: [
       { "type": "html-input", "targets": [1, 2, 3] }
    ] 
});

根据http://datatables.net/examples/api/form.html查看演示 - &gt;的 http://jsfiddle.net/a3o3yqkw/


关于实时数据:问题是,基于类型的过滤器仅称为一次。然后dataTables缓存返回的值,因此不需要反复“计算”所有值。幸运的是,dataTables 1.10.x 具有cellsrowspages的内置函数invalidate,强制dataTable重置缓存对于所选项目。

但是,在处理<input>时,也存在问题,即编辑值不会改变value属性本身。因此,即使您致电invalidate(),您仍将最终过滤旧的“硬编码”值。

但我找到了解决方法。强制使用<input>的当前值(新值)和然后调用value来更改<input>的{​​{1}}属性:

invalidate

对于textareas使用$("#example td input").on('change', function() { var $td = $(this).closest('td'); $td.find('input').attr('value', this.value); table.cell($td).invalidate(); }); 代替:

text()

处理$("#example td textarea").on('change', function() { var $td = $(this).closest('td'); $td.find('textarea').text(this.value); table.cell($td).invalidate(); }); 时也是如此。您需要更新相关<select>的{​​{1}}属性,然后更新单元格selected

<option>
分叉小提琴 - &gt; http://jsfiddle.net/s2gbafuz/ 尝试更改输入内容和/或下拉菜单,并搜索新值......

答案 1 :(得分:0)

这应该搜索整个表而不是特定的列。

var table = $('#table').DataTable();

$('#input').on('keyup', function() {
  table.search(this.val).draw();
});

答案 2 :(得分:0)

这里最好的做法是将单元格容器更新为输入中的新值,并使数据表数据对象与UI输入保持同步:

$("#pagesTable td input,#pagesTable td select").on('change', function () {
   var td = $(this).closest("td");
   dataTable.api().cell(td).data(this.value);
});

答案 3 :(得分:0)

将您的输入替换为 Textarea ,并在下面添加css。它会使你的textarea看起来像一个输入。

textarea{
    height: 30px !important;
    padding: 2px;
    overflow: hidden;
}

答案 4 :(得分:0)

如果此处要根据实时值(和“常规”单元格)搜索表中的所有输入,则可能需要构建自己的自定义搜索($.fn.DataTable.ext.search.push()):

//custom search function
$.fn.DataTable.ext.search.push((_,__,i) => {
  //get current row
  const currentTr = dataTable.row(i).node();
  //look for all <input>, <select> nodes within 
  //that row and check whether current value of
  //any of those contains searched string
  const inputMatch = $(currentTr)
    .find('select,input')
    .toArray()
    .some(input => $(input).val().toLowerCase().includes($('#search').val().toLowerCase()));
  //check whether "regular" cells contain the
  //value being searched
  const textMatch = $(currentTr)
    .children()
    .not('td:has("input,select")')
    .toArray()
    .some(td => $(td).text().toLowerCase().includes($('#search').val().toLowerCase()))
  //make final decision about match
  return inputMatch || textMatch || $('#search').val() == ''
});

此方法的完整 DEMO (您可能会在下面找到)

//sample data
const srcData = [
  {id: 1, item: 'apple', category: 'fruit'},
  {id: 2, item: 'banana', category: 'fruit'},
  {id: 3, item: 'goosberry', category: 'berry'},
  {id: 4, item: 'eggplant', category: 'vegie'},
  {id: 5, item: 'carrot', category: 'vegie'}
];

//DataTables initialization
const dataTable = $('table').DataTable({
  //minimal table config for a cleaner view
  dom: 't',
  data: srcData,
  columns: [
    {
      title: 'Id',
      data: 'id'
    },
    {
      title: 'Item', 
      data: 'item',
      //render 2-nd column cells as <input>
      render: data => `<input value="${data}"></input>`
    },
    {
      title: 'Category', 
      data: 'category',
      //render 3-rd column cells as <select>
      render: data => `<select>${['fruit', 'vegie', 'berry'].reduce((options, item) => options+='<option value="'+item+'" '+(item == data ? 'selected' : '')+'>'+item+'</option>', '<option value=""></option>')}</select>`
    }
  ]
});

//custom search function
$.fn.DataTable.ext.search.push((_,__,i) => {
  //get current row
  const currentTr = dataTable.row(i).node();
  //look for all <input>, <select> nodes within 
  //that row and check whether current value of
  //any of those contains searched string
  const inputMatch = $(currentTr)
    .find('select,input')
    .toArray()
    .some(input => $(input).val().toLowerCase().includes( $('#search').val().toLowerCase()));
  //check whether "regular" cells contain the
  //value being searched
  const textMatch = $(currentTr)
    .children()
    .not('td:has("input,select")')
    .toArray()
    .some(td => $(td).text().toLowerCase().includes($('#search').val().toLowerCase()))
  //make final decision about match
  return inputMatch || textMatch || $('#search').val() == ''
});

//trigger custom search upon search bar keyup
$('#search').on('keyup', () => dataTable.draw());
<!doctype html>
<html>
<head>
  <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
</head>
<body>
  <input id="search"></input>
  <table></table>
</body>
</html>