DataTables:如何绕过过滤规则?

Posted

技术标签:

【中文标题】DataTables:如何绕过过滤规则?【英文标题】:DataTables: How to bypass the filtering rules? 【发布时间】:2013-11-07 15:00:05 【问题描述】:

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

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

即使使用主动过滤器,这也很有效:我在记录中保留原始的、未更改的数据,同时它正在被编辑,因此我可以将这些数据用于'sort''filter' 模式mDataProp ,并且我的行保持在原位并可见,直到编辑完成。

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

我怎样才能使这个特殊行免于 DataTables 的过滤?

【问题讨论】:

【参考方案1】:

看了一段时间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 中找到 所有 未保存的记录后(使用自定义逻辑,为了这个 sn-p,我将它们包装在 is_unsaved() 函数中),我将它们全部添加到 @ 987654330@(删除这些行的现有实例后,以避免重复)。

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

【讨论】:

以上是关于DataTables:如何绕过过滤规则?的主要内容,如果未能解决你的问题,请参考以下文章

如何将过滤器和订单数据设置到 DataTables 单元格

如何将DataTables列过滤器置于顶部

DataTables 过滤输入图像变化

如何使用 jQuery DataTables 过滤某些列

DataTables+Datepicker 按日期范围过滤表格

如何从选择中搜索/过滤特定的 DataTables 列