Javascript JQuery 数据表在输入中搜索并选择
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27852497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JQuery Datatables search within input and select
提问by kralco626
Using Jquery Datatables with inputs and selects as shown here: http://datatables.net/examples/api/form.htmlor if I used a custom column render handler to produce the input and selects how can I make the global table search work?
使用带有输入和选择的 Jquery 数据表,如下所示:http: //datatables.net/examples/api/form.html或者如果我使用自定义列渲染处理程序来生成输入并选择如何使全局表搜索工作?
If you view the example you'll notice that only the first column, the read only one, is included in the search, what can I do to include the other columns in the search?
如果您查看示例,您会注意到只有第一列(只读列)包含在搜索中,我该怎么做才能将其他列包含在搜索中?
If you view the example in the link in my question and type "Tokyo" into the search all rows are returned. This is because "Tokyo" is an option in all dropdowns. I would want only rows with Tokyo selected to show. If you type in "33" you see no rows even though the first row has a value of "33" in the first column.
如果您在我的问题中查看链接中的示例并在搜索中输入“东京”,则会返回所有行。这是因为“东京”是所有下拉菜单中的一个选项。我只想显示选择了东京的行。如果您输入“33”,即使第一行的第一列值为“33”,您也看不到任何行。
I can't seem to find any documentation on how to define what the search value is for a particular cell in a datatable.
我似乎找不到任何关于如何定义数据表中特定单元格的搜索值的文档。
回答by davidkonrad
It is not very well documented. And it seems to work differently, or not work at all, between (sub)versions. I think dataTables is intended to automatically detect HTML-columns, but for some reason, most of the times, it doesnt. The safest way is to create your own search-filter :
它没有很好的记录。它似乎在(子)版本之间工作不同,或者根本不工作。我认为 dataTables 旨在自动检测 HTML 列,但出于某种原因,大多数情况下,它不会。最安全的方法是创建自己的搜索过滤器:
$.fn.dataTableExt.ofnSearch['html-input'] = function(value) {
return $(value).val();
};
This will return 33on <input>'s with value 33, and Tokyoon <select>'s where Tokyo is selected. Then define the desired columns as of type html-input;
这将返回值为 33 的33on <input>,以及选择Tokyo 的 Tokyoon <select>。然后将所需的列定义为类型html-input;
var table = $("#example").DataTable({
columnDefs: [
{ "type": "html-input", "targets": [1, 2, 3] }
]
});
see demo based on http://datatables.net/examples/api/form.html-> http://jsfiddle.net/a3o3yqkw/
参见基于http://datatables.net/examples/api/form.html-> http://jsfiddle.net/a3o3yqkw/ 的演示
Regarding live data: The issue is, that the type based filter only is called once. dataTables then caches the returned values so it not need to "calculate" all the values over and over. Luckily, dataTables 1.10.xhas a built-in function for cells, rowsand pagescalled invalidatethat forces dataTables to reset the cache for the selected items.
关于实时数据:问题是,基于类型的过滤器只被调用一次。dataTables 然后缓存返回的值,因此它不需要一遍又一遍地“计算”所有值。幸运的是,dataTables 1.10.x有一个内置函数 for cells,rows并pages调用invalidate它强制 dataTables 重置所选项目的缓存。
However, when dealing with <input>'s there is also the problem, that editing the value not is changing the valueattribute itself. So even if you call invalidate(), you will still end up in filtering on the old "hardcoded" value.
但是,在处理<input>'s 时也存在问题,即编辑值不是改变value属性本身。因此,即使您调用invalidate(),您最终仍会过滤旧的“硬编码”值。
But I have found a solution for this. Force the <input>'s valueattribute to be changed with the <input>'s current value (the new value) and thencall invalidate:
但我已经找到了解决方案。强制使用的当前值(新值)更改<input>的value属性<input>,然后调用invalidate:
$("#example td input").on('change', function() {
var $td = $(this).closest('td');
$td.find('input').attr('value', this.value);
table.cell($td).invalidate();
});
For textareas use text()instead :
对于 textareas 使用text():
$("#example td textarea").on('change', function() {
var $td = $(this).closest('td');
$td.find('textarea').text(this.value);
table.cell($td).invalidate();
});
This is also the case when dealing with <select>'s. You will need to update the selectedattribute for the relevant <option>'s and then invalidate()the cell as well :
处理<select>'s时也是如此。您将需要更新selected相关的属性<option>,然后更新invalidate()单元格:
$("#example td select").on('change', function() {
var $td = $(this).closest('td');
var value = this.value;
$td.find('option').each(function(i, o) {
$(o).removeAttr('selected');
if ($(o).val() == value) $(o).attr('selected', true);
})
table.cell($td).invalidate();
});
forked fiddle -> http://jsfiddle.net/s2gbafuz/Try change content of the inputs and/or the dropdowns, and search for the new values ...
分叉小提琴 -> http://jsfiddle.net/s2gbafuz/尝试更改输入和/或下拉列表的内容,并搜索新值...
回答by Yevgen Gorbunkov
If the point here is to search through all the inputs within a table based on the live values (and "regular" cells), you might want to build your own custom search ($.fn.DataTable.ext.search.push()):
如果此处的重点是根据实时值(和“常规”单元格)搜索表中的所有输入,您可能需要构建自己的自定义搜索 ( $.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() == ''
});
The complete DEMOof this approach you may find below:
您可以在下面找到此方法的完整演示:
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'}];
const dataTable = $('table').DataTable({dom:'t',data:srcData,columns:[{title:'Id',data:'id'},{title:'Item',data:'item',render:data=>`<input value="${data}"></input>`},{title:'Category',data:'category',render:data=>`<select>${['fruit', 'vegie', 'berry'].reduce((options, item) => options+='<option value="'+item+'" '+(item == data ? 'selected' : '')+'>'+item+'</option>', '<option value=""></option>')}</select>`}]});
$.fn.DataTable.ext.search.push((_,__,i) => {
const currentTr = dataTable.row(i).node();
const inputMatch = $(currentTr)
.find('select,input')
.toArray()
.some(input => $(input).val().toLowerCase().includes( $('#search').val().toLowerCase()));
const textMatch = $(currentTr)
.children()
.not('td:has("input,select")')
.toArray()
.some(td => $(td).text().toLowerCase().includes($('#search').val().toLowerCase()))
return inputMatch || textMatch || $('#search').val() == ''
});
$('#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>
回答by Wild Beard
This should search the entire table instead of specific column(s).
这应该搜索整个表而不是特定的列。
var table = $('#table').DataTable();
$('#input').on('keyup', function() {
table.search(this.val).draw();
});
回答by Dayan Roee
Best thing to do here is just update the cell container to the new value from the input and keep the datatable data object sync with the UI input:
这里最好的做法是将单元容器更新为输入中的新值,并使数据表数据对象与 UI 输入保持同步:
$("#pagesTable td input,#pagesTable td select").on('change', function () {
var td = $(this).closest("td");
dataTable.api().cell(td).data(this.value);
});
回答by Ricardo Gellman
Replace you input by Textarea, and add the css below. It will make your textarea looks like an input.
用Textarea替换您的输入,并在下面添加 css。它会让你的 textarea 看起来像一个输入。
textarea{
height: 30px !important;
padding: 2px;
overflow: hidden;
}

