自定义条件

SearchBuilder 允许创建自定义搜索输入框,如 插件文档 所讨论的。还可以将 searchBuilder.conditions 选项与插件 API 一起使用,以自定义 SearchBuilder 内置的默认搜索操作。本文档讨论了做这种自定义的技术,并定义了你可用作操作目标的内置搜索操作。

SearchBuilder 使用一系列对象以清晰和结构化的方式存储其条件。条件对象的第一级(searchBuilder.conditions$.fn.dataTable.SearchBuilder.conditions)是一系列键,表示 DataTables 自动检测到的列类型。可以在 columns.type 中找到更多详细信息。内置类型是

  • string
  • date
  • num
  • num-fmt
  • html
  • html-num
  • html-num-fmt

此外,当通过 datetime-moment 排序插件 使用 Moment.js 时,SearchBuilder 有自己的 moment 属性。另一个非常相似的属性通过 datetime-luxon 排序插件 提供 Luxon 支持。还有一个 array 属性,它提供针对类似数组的数据优化的条件。SearchBuilder 将自动检测和处理这些列中的数据,但 array 条件除外,在这种情况下,必须将 columns.type 设置为 array。还可以向该对象添加自己的列类型,请再次查阅 columns.type 以了解如何执行此操作的更多信息。

每个类型都是一个定义可应用于该类型的数据的条件的对象。条件对象的实际名称根本不会呈现给用户,但用有帮助开发人员理解该条件将做什么名称来为其命名会很有用(例如 = 表示直接比较条件)。

考虑到所有这些,无论想如何更改条件,都将使用以下基本结构。这里使用了 num 列类型。

$('#example').DataTable({
    searchBuilder: {
        conditions: {
            num: {
                ...
            }
        }
    }
})

在本页的其余部分,num 条件将用于演示如何删除、编辑和创建条件。标准的 num 条件如下:

  • = - 等于
  • != - 不等于
  • !null - 非空
  • < - 小于
  • <= - 小于等于
  • > - 大于
  • >= - 大于等于
  • null - 空/空值
  • between - 之间
  • !between - 非之间

注:请注意,当 serverSide 选项设置为 true 时,不支持自定义条件。

删除条件

删除条件是编辑条件的最简单方法。例如,如果你想删除 !between 条件,只需将 searchBuilder.conditions.num 对象中的该条件设置为 null

$('#example').DataTable({
    searchBuilder: {
        conditions: {
            num: {
                '!between': null
            }
        }
    }
})

或使用以下方法从所有表中删除该条件

delete $.fn.dataTable.SearchBuilder.conditions.num['!between'];

这将从用户在选择类型为 num 的列时看到条件列表中删除“非之间”条件。

编辑条件

在每个条件中,有五项属性可以编辑以影响行为。

conditionName

searchBuilder.conditions[type].conditionName 是显示给用户在每个条件的选择元素中的 string 值。有关如何编辑该选择元素占位符的文档,请参见 language.searchBuilder.condition。要将 > 条件的显示字符串从 Greater Than 编辑为 Above,请执行以下操作。

$('#example').DataTable({
    searchBuilder: {
        conditions: {
            num: {
                '>': {
                    conditionName: 'Above'
                }
            }
        }
    }
})

或对所有表

$.fn.dataTable.SearchBuilder.conditions.num['>'].conditionName = 'Above';

init

searchBuilder.condition[type].init 函数用于初始化从用户获取该条件值的任何 jQuery 元素。标准 searchBuilder.condition[type].init 函数如下所示。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                '>': {
                    init: function(that, fn, preDefined = null) {
                        // Declare the input element
                        let el = $('<input/>')
                            .addClass(that.classes.value)
                            .addClass(that.classes.input)
                            .on('input', function() { fn(that, this); });

                        // If there is a preDefined value then add it
                        if (preDefined !== null) {
                            $(el).val(preDefined[0]);
                        }

                        return el;
                    }
                }
            }
        }
    }
})

searchBuilder.condition[type].init 函数采用三个参数。

  • that - 这是对正在设置条件的条件实例。传入此参数可访问现有的类和内部属性。请注意,在此处更改条件实例的内部属性可能会导致未定义的行为。
  • fn - 这是当您希望执行搜索时必须调用的回调函数。对于输入元素,每次输入输入元素时,就应触发搜索。因此,在输入元素的 input 监听器中调用该函数。
  • preDefined - 这是设置或之前存在于值中的任何值的传递位置。SearchBuilder 使用它,因此必须存在,即使你不设置预定义值也必须存在。如果你不添加此值,那么输入元素可能会在每次按键时重置为空白。

searchBuilder.condition[type].init 函数返回一个用于从用户中获取值的 jQuery 元素。这里可以创建多个元素,如果这样的话,将返回一个元素数组,而不是一个单独元素。还可以在此通过将元素附加到 div 来创建更复杂结构。确实有非常广泛的可能性。

下面是一个例子,显示了如何在应用某些自定义类的 span 中返回一个 input 元素。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                '>': {
                    init: function(that, fn, preDefined = null) {
                        // Declare span wrapper for input
                        var span = $('<span/>')
                            .addClass('mySpan');

                        // Declare the input element
                        var el = $('<input/>')
                            .addClass(that.classes.value)
                            .addClass(that.classes.input)
                            .addClass('myInput')
                            .on('input', function() { fn(that, this); });

                        // If there is a preDefined value then add it
                        if (preDefined !== null) {
                            $(el).val(preDefined[0]);
                        }

                        // Append input element to span
                        $(span).append(el);

                        return span;
                    }
                }
            }
        }
    }
})

inputValue

searchBuilder.conditions[type].inputValue 函数用于从 searchBuilder.conditions[type].init 函数中创建的元素中提取值,如上面详细说明。最有可能的情况是,如果你对 searchBuilder.conditions[type].init 函数中涉及元素进行了更改,那么你也必须对 searchBuilder.conditions[type].inputValue 函数进行一些更改。

下面是一个基于上文 searchBuilder.conditions[type].init 函数下所列的 jQuery 结构的示例。它有两个参数。

  • el - 从 init 函数返回的 jQuery 元素数组。
  • that - 当前被考虑的 criteria 实例。
$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                '>': {
                    inputValue: function(el, that) {
                        return [$(el[0]).children()[0].val()];
                    }
                }
            }
        }
    }
})

这里我们仅仅访问 span 的唯一子项,即 input 元素。然后可以读取它的值并返回。

isInputValid

searchBuilder.conditions[type].inputValue 函数用于确定是否应将 criteria 包含在最终搜索结果中。这是因为我们不想包含不完整或空的 criteria,这可能会导致不需要的结果。searchBuilder.conditions[type].inputValue 函数采用 2 个参数

  • el - 从 init 函数返回的 jQuery 元素数组。
  • that - 当前被考虑的 criteria 实例。
$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                '>': {
                    isInputValid: function(el, that) {
                        return $(el[0]).children()[0].val().length > 0; // Check that the input element has some content
                    }
                }
            }
        }
    }
})

此处,在搜索过程中考虑 criteria 之前,正在检查 input 元素,以查看 input 元素中是否有一些内容。如果你总想考虑 criteria,无论收集到的值是什么,那么只需从该函数返回 true 即可。

search

在搜索数据表以决定要包含哪些结果时,使用 searchBuilder.conditions[type].search 函数。它采用两个参数。

  • value - 这是要比较的数据表的数值。SearchBuilder 通过使用 criteria 中的数据选择元素,自动选择准确的数据点。
  • comparison - 这是从 searchBuilder.conditions[type].inputValue 函数返回的值数组。

我们考虑此示例中的介于条件,此条件通过两个输入元素获取两个值,标准形式为

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'between': {
                    search: function(value, comparison) {
                        // Depending on which input element is bigger will change the comparisons that need to be made
                        if (+comparison[0] < +comparison[1]) {
                            return +comparison[0] <= +value && +value <= +comparison[1];
                        }
                        else {
                            return +comparison[1] <= +value && +value <= +comparison[0];
                        }
                    }
                }
            }
        }
    }
})

在此表中介于或等于比较值的任何值都将显示在表中,假设要编辑条件,以便仅包括介于比较值之间的值而不包括比较值本身,则会对条件进行以下细微的更改。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'between': {
                    search: function(value, comparison) {
                        // Depending on which input element is bigger will change the comparisons that need to be made
                        if (+comparison[0] < +comparison[1]) {
                            return +comparison[0] < +value && +value < +comparison[1];
                        }
                        else {
                            return +comparison[1] < +value && +value < +comparison[0];
                        }
                    }
                }
            }
        }
    }
})

创建条件

创建条件只是简单地获取在“编辑条件”部分中讨论过的所有属性并将它们组合在一起的事项。以下详细介绍如何创建“倍数”筛选器,为了创建筛选器,我们必须将对象添加到 num 类型对象中。这将意味着类似于以下内容。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    ...
                }
            }
        }
    }
})

conditionName

正如前面讨论的那样,searchBuilder.conditions[type].conditionName 只是将在条件选择元素中显示的字符串。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    conditionName: 'Multiple Of'
                }
            }
        }
    }
})

init

对于searchBuilder.conditions[type].init函数,我们不必使用太复杂的东西。一个简单的输入元素将很好地用于此目的。除了声明一个 jQuery 输入元素,还需要为回调函数设置侦听器,该函数引入搜索功能并创建重新加载预定义值的方法。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    conditionName: 'Multiple Of',
                    init: function (that, fn, preDefined = null) {
                        // Create input element and add the classes to match the SearchBuilder styles
                        var el = $('<input/>')
                            .addClass(that.classes.input)
                            .addClass(that.classes.value)

                        // Add the listener for the callback search function
                        $(el).on('input', function () {
                            fn(that, this);
                        });

                        // Set any preDefined values
                        if (preDefined !== null) {
                            el.val(preDefined[0]);
                        }

                        return el;
                    }
                }
            }
        }
    }
})

inputValue

同样,searchBuilder.conditions[type].inputValue 函数也可以相当简单,我们只需要从输入元素中提取值即可。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    conditionName: 'Multiple Of',
                    init: function (that, fn, preDefined = null) {
                        // Create input element and add the classes to match the SearchBuilder styles
                        var el = $('<input/>')
                            .addClass(that.classes.input)
                            .addClass(that.classes.value)

                        // Add the listener for the callback search function
                        $(el).on('input', function () {
                            fn(that, this);
                        });

                        // Set any preDefined values
                        if (preDefined !== null) {
                            el.val(preDefined[0]);
                        }

                        return el;
                    },
                    inputValue: function (el, that) {
                        // return the value in the input element
                        return [$(el[0]).val()];
                    }
                }
            }
        }
    }
})

isInputValid

同样,searchBuilder.conditions[type].isInputValid 函数也可以相当简单。所需的只是检查输入元素中是否有一些文本。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    conditionName: 'Multiple Of',
                    init: function (that, fn, preDefined = null) {
                        // Create input element and add the classes to match the SearchBuilder styles
                        var el = $('<input/>')
                            .addClass(that.classes.input)
                            .addClass(that.classes.value)

                        // Add the listener for the callback search function
                        $(el).on('input', function () {
                            fn(that, this);
                        });

                        // Set any preDefined values
                        if (preDefined !== null) {
                            el.val(preDefined[0]);
                        }

                        return el;
                    },
                    inputValue: function (el, that) {
                        // return the value in the input element
                        return [$(el[0]).val()];
                    },
                    isInputValid: function (el, that) {
                        return $(el).val().length > 0;
                    }
                }
            }
        }
    }
})

search

searchBuilder.conditions[type].search 函数是条件将需要最多“新建”代码的地方。不过,尽管如此,它仍然很容易。要找出某个数字是否是另一个数字的倍数,我们只需使用模数 (%) 运算符来检查余数是否为 0 即可。

$('#example').DataTable({
    searchBuilder:{
        conditions:{
            num:{
                'multiple': {
                    conditionName: 'Multiple Of',
                    init: function (that, fn, preDefined = null) {
                        // Create input element and add the classes to match the SearchBuilder styles
                        var el = $('<input/>')
                            .addClass(that.classes.input)
                            .addClass(that.classes.value)

                        // Add the listener for the callback search function
                        $(el).on('input', function () {
                            fn(that, this);
                        });

                        // Set any preDefined values
                        if (preDefined !== null) {
                            el.val(preDefined[0]);
                        }

                        return el;
                    },
                    inputValue: function (el, that) {
                        // return the value in the input element
                        return [$(el[0]).val()];
                    },
                    isInputValid: function (el, that) {
                        return $(el).val().length > 0;
                    },
                    search: function (value, comparison) {
                        return value % comparison[0] === 0;
                    }
                }
            }
        }
    }
})

可以在这里找到具有此自定义条件的示例here

另一篇可能有用的页面是 SearchBuilder 插件页面