DataTables:如何绕过过滤规则?

时间:2013-10-28 17:44:33

标签: javascript jquery datatables inline-editing

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

后台:我正在使用基于jQuery的DataTables.js库构建表格编辑组件。我想在数据表中直接显示编辑控件,而不是使用对话框或叠加层,如下所示:

enter image description here

即使使用有效过滤器,这也像魅力一样:我在编辑时保留原始未更改的数据,因此我可以将这些数据用于'sort''filter'模式mDataProp的{​​{1}},我的行保持原位并可见,直到编辑完成。

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

enter image description here

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

1 个答案:

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

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