【发布时间】:2019-09-17 10:16:56
【问题描述】:
应用程序正在使用:
- 数据表 1.10.18
- jQuery 3.2.1
- PHP 后端
- lodash 4.17.4
应用程序包含一个由多个数据表组成的网页。其中每一个都使用serverSide: true(服务器端模式)通过返回 JSON 数据的 ajax 端点获取数据。
表初始化如下:
-
在页面加载时会呈现几个
<table>。我正在使用 jquery.each()为每个初始化 DataTable:$.each($('table'), function () { $(this).DataTable({ processing: true, serverSide: true, searching: false, ajax: { data: { table_id: $(this).attr('id') }, url: '/get-data.json', }, ... }); 每个
<table>都有一个ID。这是通过data:属性中的 ajax 传递的。端点/get-data.json根据表ID返回数据。换句话说,它根据这个ID知道应该为“哪个表”获取数据。
我希望能够在表格上进行搜索,但必须在服务器端完成。出于这个原因,我在 (1) 中的初始化代码设置了 searching: false,因为这有效地禁用了 DataTables 提供的客户端搜索工具(我们不能在这种情况下使用它,因为搜索必须在服务器端完成)。
我面临的问题是如何为每个表创建搜索输入、进行 ajax 调用并更新相应的表。我希望在输入 >=3 个字符后实时搜索。这个问题的关键是 1 个搜索输入负责搜索 1 个数据表 - 它 不是 一个搜索功能,其中输入可以更新“页面上的任何/每个表”,这是其他常用描述的模式问题。 1 个输入:在这种情况下搜索 1 个表。
我的计划如下 - 第 (2) 点中引用的每个表都有一个 ID。我需要创建独特的输入。因此,如果我有 ID 为 #table1、#table2、#table3 的表,我可以轻松创建:
<input type="text" name="table1_search" id="table1_search">
<input type="text" name="table2_search" id="table2_search">
<input type="text" name="table3_search" id="table3_search">
然后我检测输入是否发生了任何变化:
$('input[type="text"]').bind("keyup change input",
function (e) {
// Ignore tab key for keyup event otherwise it'll fire an ajax request that does nothing useful.
if (e.which !== 9) {
processSearch.call(this);
} else {
e.preventDefault();
}
});
var prev_value = {};
function processSearch() {
var obj = $(this),
search_id = obj.attr('id'), // ID of input
search_value = obj.val(); // Value of input
// There's been no change to the field, ignore.
if (prev_value[search_id] === search_value) {
return;
}
prev_value[search_id] = search_value;
/* Wait until at least 3 characters have been entered, or user has cleared the input */
if (search_value.length >= 3 || (!search_value)) {
debouncedDraw({search_id: search_id, search_value: search_value});
}
}
上面的代码在等待输入 >=3 个字符方面完成了我所需要的。然后我正在执行一个名为debouncedDraw 的函数,它传递一个包含search_id 和search_value 的对象。这些分别指的是输入 ID 和值,例如如果我在#table1_search 中输入“foo”,那么对象是:
{search_id: 'table1_search', search_value: 'foo'}
debouncedDraw 函数如下所示。这是使用lodash 来限制函数可以触发的速率。这里的重点是根据我几年前在这里提出的一个问题来阻止它发出不必要的 ajax 请求:DataTables - kill ajax requests when a new one has started:
var debouncedDraw = _.debounce(function (opts) {
console.log(opts);
}, 500);
目前这只是console.log上面给出的对象。
我不确定目前进行的最佳方式。我需要通过 ajax 重新运行/get-data.json,然后更新相应的表。
我可以访问请求数据并根据下划线拆分search_id,以计算出数据用于哪个表ID(例如table1_search目标#table1)。然后我需要将此数据写回相应的表(在这种情况下为#table1)。
我不禁想我会以一种令人费解的方式来解决这个问题,并想知道 DataTables 本身是否有更好的方法来支持这一点?这似乎是一个非常基本的要求(serverSide 模式下的多个可搜索表)。但我找不到任何具体说明如何执行此操作的帖子。
【问题讨论】:
标签: javascript php jquery ajax datatables