Поиск JQuery Datatables внутри ввода и выбора
Использование JQuery Datatables со входами и выборами, как показано здесь: http://datatables.net/examples/api/form.html
или если я использовал обработчик обработчика собственного столбца для ввода ввода и выбирает, как я могу заставить глобальный поиск в таблице работать?
Если вы посмотрите пример, вы заметите, что в поиск включен только первый столбец, только для чтения, что я могу сделать, чтобы включить другие столбцы в поиск?
Если вы посмотрите пример в ссылке в моем вопросе и введите "Токио" в поиск, все строки будут возвращены. Это связано с тем, что "Токио" является вариантом во всех выпадающих списках. Я бы хотел, чтобы только строки с Токио были отобраны для показа. Если вы наберете "33", вы увидите строки, даже если первая строка имеет значение "33" в первом столбце.
Я не могу найти какую-либо документацию о том, как определить, какое значение поиска для конкретной ячейки в datatable.
Ответы
Ответ 1
Это не очень хорошо задокументировано. И кажется, что он работает по-разному или вообще не работает между (под) версиями. Я думаю, что dataTables предназначен для автоматического обнаружения HTML-столбцов, но по некоторым причинам, в большинстве случаев, это не так. Самый безопасный способ - создать собственный поисковый фильтр:
$.fn.dataTableExt.ofnSearch['html-input'] = function(value) {
return $(value).val();
};
Это вернет 33 на <input>
со значением 33 и Tokyo на <select>
где выбран Tokyo. Затем определите нужные столбцы с типом html-input
;
var table = $("#example").DataTable({
columnDefs: [
{ "type": "html-input", "targets": [1, 2, 3] }
]
});
см. демонстрацию на основе http://datatables.net/examples/api/form.html → http://jsfiddle.net/a3o3yqkw/
Что касается оперативных данных: проблема в том, что фильтр на основе типов вызывается только один раз. Затем dataTables кэширует возвращаемые значения, поэтому не нужно "вычислять" все значения снова и снова. К счастью, dataTables 1.10.x имеет встроенную функцию для cells
, rows
и pages
называемую invalidate
которая заставляет dataTables сбрасывать кэш для выбранных элементов.
Однако при работе с <input>
также возникает проблема, заключающаяся в том, что редактирование значения не приводит к изменению самого атрибута value
. Таким образом, даже если вы вызовете 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();
});
Для text()
полей используйте text()
вместо этого:
$("#example td textarea").on('change', function() {
var $td = $(this).closest('td');
$td.find('textarea').text(this.value);
table.cell($td).invalidate();
});
Это также имеет место при работе с <select>
. Вам нужно будет обновить 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();
});
разветвленная скрипка → http://jsfiddle.net/s2gbafuz/ Попробуйте изменить содержимое входов и/или раскрывающихся списков и найдите новые значения...
Ответ 2
Если целью здесь является поиск по всем входным данным в таблице на основе текущих значений (и "обычных" ячеек), вам может потребоваться создать собственный настраиваемый поиск ($.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() == ''
});
Полное ДЕМО этого подхода вы можете найти ниже:
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>
Ответ 3
Это должно искать всю таблицу вместо конкретных столбцов.
var table = $('#table').DataTable();
$('#input').on('keyup', function() {
table.search(this.val).draw();
});
Ответ 4
Лучше всего здесь просто обновить контейнер ячейки до нового значения из ввода и сохранить синхронизируемый объект данных данных с входом пользовательского интерфейса:
$("#pagesTable td input,#pagesTable td select").on('change', function () {
var td = $(this).closest("td");
dataTable.api().cell(td).data(this.value);
});
Ответ 5
Замените ввод Textarea и добавьте css ниже. Это заставит ваше текстовое поле выглядеть как вход.
textarea{
height: 30px !important;
padding: 2px;
overflow: hidden;
}