0

如何从 DataTables 的内置过滤中免除 DataTables.js 表中的单行,以便始终显示它?

背景:我正在使用基于 jQuery 的DataTables.js库构建一个表格编辑组件。我不想使用对话框或覆盖,而是想在数据表中显示编辑控件,如下所示:

在此处输入图像描述

这就像一个魅力,即使使用活动过滤器:我在编辑时将原始的、未更改的数据保留在记录中,因此我可以将这些数据用于'sort''filter'模式mDataProp,并且我的行保持原位并可见,直到编辑完成完成的。

当我添加一个新行时会出现一个更大的问题:没有用于过滤的数据,所以如果一个过滤器处于活动状态,我的行将不可见。这破坏了用户搜索数据集的工作流程,发现缺少某些记录,并且(不清除过滤器)按下“添加”按钮,等待出现带有编辑控件的空行:

在此处输入图像描述

如何从 DataTables 的过滤中免除此特殊行?

4

1 回答 1

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(在删除这些行的现有实例之后,以避免重复)。

这种特定实现的副作用是所有未保存的行都出现在表的顶部,但在我的情况下,这实际上是可取的。

于 2013-10-28T17:44:32.900 回答