如何从DataTables的内置过滤中豁免DataTables.js表中的单行,以便始终显示它?
后台:我正在使用基于jQuery的DataTables.js库构建表格编辑组件。我想在数据表中直接显示编辑控件,而不是使用对话框或叠加层,如下所示:
即使使用有效过滤器,这也像魅力一样:我在编辑时保留原始未更改的数据,因此我可以将这些数据用于'sort'
和'filter'
模式mDataProp
的{{1}},我的行保持原位并可见,直到编辑完成。
添加新行时会出现更大的问题:没有可用于过滤的数据,因此如果过滤器处于活动状态,则我的行将不可见。这会破坏用户搜索数据集的工作流程,看到缺少某些记录,并且(不清除过滤器)按下“添加”按钮,等待带有编辑控件的空行显示:
如何从DataTables的过滤中免除此特殊行?
答案 0 :(得分:0)
在阅读了DataTables.js的源代码一段时间后,我得出结论,没有办法以所需的方式挂钩过滤。有自定义过滤器的钩子,但它们只能用于隐藏东西,而不是用来显示东西。
但是,有一个'filter'
事件在过滤后触发,但在呈现表之前触发。我的解决方案为此事件安装了一个处理程序:
$('table#mydatatable').bind('filter', function() {
var nTable = $(this).dataTable();
var oSettings = nTable.fnSettings();
//collect the row IDs of all unsaved rows
var aiUnsavedRowIDs = $.grep(oSettings.aiDisplayMaster, function(iRowID) {
var oRowData = nTable.fnGetData(iRowID);
return is_unsaved(oRowData);
});
//prepare lookup table
var oUnsavedRecordIDs = {};
$.each(aiUnsavedRowIDs, function(idx, iRowID) {
oUnsavedRecordIDs[iRowID] = true;
});
//remove unsaved rows from display (to avoid duplicates after the
//following step)
for (var i = oSettings.aiDisplay.length; i >= 0; i--) {
//iterate backwards, because otherwise, removal from aiDisplay
//would mess up the iteration
if (oUnsavedRecordIDs[ oSettings.aiDisplay[i] ]) {
oSettings.aiDisplay.splice(i, 1);
}
}
//insert unsaved records at the top of the display
Array.prototype.unshift.apply(oSettings.aiDisplay, aiUnsavedRowIDs);
//NOTE: cannot just say oSettings.aiDisplay.unshift(aiUnsavedRowIDs)
//because this would add the array aiUnsavedRowIDs as an element to
//aiDisplay, not its contents.
});
这里发生了什么?首先,我通过浏览oSettings.aiDisplayMaster
找到所有未保存的行。此数组以正确的排序顺序引用此DataTable中的所有行。 aiDisplayMaster
的元素是DataTables内部数据存储的整数索引(每行一个索引)。
过滤过程遍历aiDisplayMaster
中的行,并将所有匹配行的行ID放在oSettings.aiDisplay
中。此数组控制将呈现哪些行(在此事件处理程序完成之后!)。整个过程如下:
[1, ..., numRows]
|
| sorting
v
oSettings.aiDisplayMaster
|
| filtering
v
oSettings.aiDisplay
|
| rendering
v
DOM
因此,在aiDisplayMaster
中找到所有未保存的记录后(使用我在is_unsaved()
函数中包含的自定义逻辑,为了此代码段),我将它们全部添加到aiDisplay
(删除这些行的现有实例后,以避免重复)。
此特定实现的副作用是所有未保存的行都显示在表的顶部,但在我的情况下,这实际上是可取的。