单击标题内的输入字段时,DataTables 过滤列

Posted

技术标签:

【中文标题】单击标题内的输入字段时,DataTables 过滤列【英文标题】:DataTables filters column when clicking on input field inside Header 【发布时间】:2021-12-19 03:38:48 【问题描述】:

我有一个 DataTables 实例,它在表的标题中附加了一个选择。 Here 是一个显示它的代码笔。

这是将选择添加到标题的代码的相关部分

        initComplete: function () 
            count = 0;
            this.api().columns().every(function () 
                var title = this.header();
                //replace spaces with dashes
                title = $(title).html().replace(/[\W]/g, '-');
                var column = this;
                var select = $('<br><select id="' + title + '" class="select2" ></select>')
                    .appendTo($(column.header()))
                    .on('change', function () 
                        //Get the "text" property from each selected data
                        //regex escape the value and store in array
                        var data = $.map($(this).select2('data'), function (value, key) 
                            return value.text ? '^' + $.fn.dataTable.util.escapeRegex(value.text) + '$' : null;
                        );

                        //if no data selected use ""
                        if (data.length === 0) 
                            data = [""];
                        

                        //join array into string with regex or (|)
                        var val = data.join('|');

                        //search for the option(s) selected
                        column
                            .search(val ? val : '', true, false)
                            .draw();
                    );
                //unique, tipo group by 
                //sorte deixa em ordem abcd
                column.data().unique().sort().each(function (d, j) 
                    select.append('<option value="' + d + '">' + d + '</option>');
                );

                //use column title as selector and placeholder
                $('#' + title).select2(
                    multiple: true,
                    closeOnSelect: false,
                    placeholder: "Select a " + title
                );

                //initially clear select otherwise first option is selected
                $('.select2').val(null).trigger('change');
            );
        

但是我注意到将它放在标题中的一个缺点是,当我单击选择时,DataTables 认为我正在按该列排序。如果我在选择内单击(其 ID 等于列名),有没有办法不对列进行排序

编辑:我正在寻找一种解决方案,当我单击标题列内的 input 元素时不会触发列排序。

【问题讨论】:

【参考方案1】:

有两种方法可以做到。

首先是完全禁用点击排序。只需将其放在您的表格选项中即可:

ordering: false,

另一种选择是在标题中有两行。第一行应该是带有列标题的th,第二行应该是td 单元格内的下拉过滤器。这是因为 DataTables 在th 单元格内为排序箭头保留了一个空间,即使它们不存在。

<thead>
    <tr>
        <th>Demanda</th>
        <th>Título</th>
        <th>Solicitante</th>
        <th>Data Inclusao</th>
        <th>Área</th>
        <th>SP</th>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</thead>

您需要将您的 appendTo() 更改为以下内容:

.appendTo($(`#example thead tr:eq(1) td`).eq(this.index()))

然后在你的表格选项中你可以设置

orderCellsTop: true,

当您单击顶部标题行并从第二个标题行的下拉列表中过滤时,这将允许排序。

【讨论】:

此解决方案有效,但不一定是我想要的。使用第二行看起来很奇怪,因为只有 2 列有下拉菜单。我宁愿这样做,这样输入中的 onclick 就不会排序【参考方案2】:

我为同样的问题提出的最简单的解决方案是:

document.addEventListener("click", e => 
    var target = e.target;
    if ($(target).closest("th").hasClass("sorting") && $(target).prop("tagName") == "INPUT") 
        /* You can replace or add more element types in condition. */
        e.stopPropagation();
        e.preventDefault();
    
, true);

【讨论】:

这对于不触发排序非常有效,但是如果您单击下拉列表中的一个项目(li 元素之一,它将触发排序。我什至添加了一个检查 @987654324 @ 是 LIe.stopPropagation();e.preventDefault(); 并没有停止排序。 尝试根据您的情况将$(target).prop("tagName") == "INPUT" 替换为$(target).closest("span.select2-container").length &gt; 0 还是一样。我测试并用您的新.closest() 代码替换所有内容(长度为 1),e.stopPropagation();e.preventDefault(); 不执行任何操作。我最新的codepen 显示了这一点。

以上是关于单击标题内的输入字段时,DataTables 过滤列的主要内容,如果未能解决你的问题,请参考以下文章

jQuery DataTables 鼠标点击搜索

JQuery1.8 Datatables单击按钮保存状态

当用户单击 UIWebView 内的文本字段时,出现键盘后屏幕不会向上移动

DataTables 列过滤器因 FixedHeader 失败

过滤 dataTables.net,不包含过滤框输入

用于过滤的 DataTables 第二个标题行