jQuery DataTables:输入至少3个字符或者点击按钮后再进行搜索

92

是否有选项只在输入三个字符后开始搜索?

我为同事编写了一个显示20,000条目的PHP脚本,他们抱怨当输入单词时,前几个字母会导致一切都冻结。

另一种选择是通过点击按钮而不是键入字符来启动搜索。

以下是我的当前代码:

$("#my_table").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "bAutoWidth": false,
        "aoColumns": [
                /* qdatetime */   { "bSearchable": false },
                /* id */          null,
                /* name */        null,
                /* category */    null,
                /* appsversion */ null,
                /* osversion */   null,
                /* details */     { "bVisible": false },
                /* devinfo */     { "bVisible": false, "bSortable": false }
        ],
        "oLanguage": {
                "sProcessing":   "Wait please...",
                "sZeroRecords":  "No ids found.",
                "sInfo":         "Ids from _START_ to _END_ of _TOTAL_ total",
                "sInfoEmpty":    "Ids from 0 to 0 of 0 total",
                "sInfoFiltered": "(filtered from _MAX_ total)",
                "sInfoPostFix":  "",
                "sSearch":       "Search:",
                "sUrl":          "",
                "oPaginate": {
                        "sFirst":    "<<",
                        "sLast":     ">>",
                        "sNext":     ">",
                        "sPrevious": "<"
                },
                "sLengthMenu": 'Display <select>' +
                        '<option value="10">10</option>' +
                        '<option value="20">20</option>' +
                        '<option value="50">50</option>' +
                        '<option value="100">100</option>' +
                        '<option value="-1">all</option>' +
                        '</select> ids'
        }
} );

1
仅针对延迟,在dataTable配置中尝试以下操作 { searchDelay: value } value是以毫秒为单位的整数 - Avi
24个回答

95

版本1.10的解决方案 -

在这里寻找完整答案并找不到后,我编写了以下内容(利用文档中的代码和一些答案)。

以下代码可延迟搜索直至输入至少3个字符:

// Call datatables, and return the API to the variable for use in our code
// Binds datatables to all elements with a class of datatable
var dtable = $(".datatable").dataTable().api();

// Grab the datatables input box and alter how it is bound to events
$(".dataTables_filter input")
    .unbind() // Unbind previous default bindings
    .bind("input", function(e) { // Bind our desired behavior
        // If the length is 3 or more characters, or the user pressed ENTER, search
        if(this.value.length >= 3 || e.keyCode == 13) {
            // Call the API search function
            dtable.search(this.value).draw();
        }
        // Ensure we clear the search if they backspace far enough
        if(this.value == "") {
            dtable.search("").draw();
        }
        return;
    });

4
如果你在使用此功能时遇到了问题,可以尝试在 init.dt 事件中使用它,例如:$('#yourTable').on('init.dt', function () { ... });。请注意,这里不提供任何解释以外的内容。 - arao6
3
我之前使用了“input”而不是“keydown”函数,现在它已经很好地工作了。谢谢。 - azza idz
1
@Maxime 我已经将其回滚到可行的编辑版本,并且没有出现那些错误的变量名称不匹配。如果您认为仍需要编辑/注意,请告诉我。 - random_user_name
2
@cale_b 我可以确认这在1.10.16版本仍然有效。谢谢。 - AnotherDeveloper
3
2020年有更好的解决方案吗? :) - Hackeron
显示剩余16条评论

77

注意:这是早期版本的数据表格,如果使用jQuery datatables v1.10及更高版本,请参阅此答案


这将修改输入框的行为,只有在按下回车键或搜索中至少有3个字符时才会进行过滤:

$(function(){
  var myTable=$('#myTable').dataTable();

  $('.dataTables_filter input')
    .unbind('keypress keyup')
    .bind('keypress keyup', function(e){
      if ($(this).val().length < 3 && e.keyCode != 13) return;
      myTable.fnFilter($(this).val());
    });
});
你可以在这里看到它的工作原理:http://jsbin.com/umuvu4/2。我不知道为什么dataTables的人既绑定了keypress又绑定了keyup,但我覆盖了这两个事件以保持兼容,尽管我认为keyup足够了。
希望这会有所帮助!

2
注意到这一点了。绑定按键和释放按键两者意味着查询会触发两次。对于在家观看的人,您应该从解除绑定和绑定中只删除其中一个。 - Thunder Rabbit
1
这个解决方案在按退格键时不起作用。@Sam Barnes是最佳答案。 - Idrees Khan
2
作为 Sam Barnes 出色答案的替代方案,您可以将其修改以考虑退格(和清除字段),方法是将 e.keycode != 13 替换为 e.keyCode > 13,这样当他们从该字段中切出时也会触发。 - cincodenada
2
很遗憾,这在1.10版本中无法工作 - random_user_name
根据@ThunderRabbit的建议,我发现最好的方法是解绑两个事件,然后重新绑定其中一个事件。.unbind('keypress keyup').bind('keypress', function(e) ... - nageeb
显示剩余2条评论

32

为什么不尝试一下 Stony 的答案的扩展版本呢 :)

var searchWait = 0;
var searchWaitInterval;
$('.dataTables_filter input')
.unbind('keypress keyup')
.bind('keypress keyup', function(e){
    var item = $(this);
    searchWait = 0;
    if(!searchWaitInterval) searchWaitInterval = setInterval(function(){
        if(searchWait>=3){
            clearInterval(searchWaitInterval);
            searchWaitInterval = '';
            searchTerm = $(item).val();
            oTable.fnFilter(searchTerm);
            searchWait = 0;
        }
        searchWait++;
    },200);

});
这将延迟搜索,直到用户停止输入。
希望对你有所帮助。

工作得很好。但我必须更改oTable.fnFilter(...)以引用我的数据表实例。 - YudhiWidyatama
这并不是扩展版本,而是完全不同(但有用)的解决方案。然而,我对searchWait参数的作用感到困惑,因为似乎可以通过setTimeout(function(){...}, 600)来实现,因为该函数似乎不会在进一步输入字符时重新触发。 - cincodenada
@cincodenada 必须使用 setInterval,因为它每200/600毫秒重新启动一次,并检查是否将 searchWait 重置为0。例如,如果您继续向输入框输入内容,则会始终将 searchWait 重置为0 = 搜索永远不会执行。但是,我发现将 searchWait 用作计数到3的整数相当晦涩。更好的方法是使用一个 true/false 标志来表示用户输入是否发生,并使用 600 的 setInterval - r3mark
3
自jQuery Datatables 1.10.3版本以来,就有一个名为“searchDelay”的选项可供使用。searchDelay - panmari
2
@panmari - searchDelay 只会延迟指定时间的搜索,并在此之后重新绘制表格(触发 ajax),而不是当用户停止输入时,这是我们大多数人所期望的。 - Chris Landeza

13

以下是如何处理版本1.10中的API更改

var searchbox = $('#promogrid_filter input');
var pgrid = $('#promogrid').DataTable();

//Remove default datatable logic tied to these events
searchbox.unbind();

searchbox.bind('input', function (e) {
   if(this.value.length >= 3) {
      pgrid.search(this.value).draw();
   }
   if(this.value == '') {
      pgrid.search('').draw();
   }
   return;
});

8

这适用于DataTables 1.10.4:

var table = $('#example').DataTable();

$(".dataTables_filter input")
    .unbind()
    .bind('keyup change', function(e) {
        if (e.keyCode == 13 || this.value == "") {
            table
                .search(this.value)
                .draw();
        }
    });

JSFiddle


8

我的datatables版本是1.10.10

我做了一些小改动,现在可以正常工作了。所以我分享出来,因为让它在1.10.10版本上运行起来很困难。感谢cale_b、Stony和Sam Barnes。查看代码以了解我所做的。

    var searchWait = 0;
    var searchWaitInterval;
    $('.dataTables_filter input')
    .unbind() // leave empty here
    .bind('input', function(e){ //leave input
        var item = $(this);
        searchWait = 0;
        if(!searchWaitInterval) searchWaitInterval = setInterval(function(){
            if(searchWait >= 3){
                clearInterval(searchWaitInterval);
                searchWaitInterval = '';
                searchTerm = $(item).val();
                oTable.search(searchTerm).draw(); // change to new api
                searchWait = 0;
            }
            searchWait++;
        },200);

    });

8
为了在用户在搜索框中键入最少字符后调用服务器调用,您可以按照Allan的建议

自定义 fnSetFilteringDelay()插件API函数以添加 在设置过滤器之前对字符串长度进行额外的条件考虑空白字符串输入以清除过滤器。

因此,对于至少3个字符,请只需更改插件中的第19行:

if ((anControl.val().length == 0 || anControl.val().length >= 3) && (sPreviousSearch === null || sPreviousSearch != anControl.val())) {

2
这是针对最新版本1.11.x的正确解决方案。它将搜索延迟技巧与触发搜索所需的最小字符数结合起来。所有其他解决方案仅部分起作用。非常感谢! - Luciano Fantuzzi

7
这是一个类似插件的脚本,可扩展数据表格。
jQuery.fn.dataTableExt.oApi.fnSetFilteringEnterPress = function ( oSettings ) {
    var _that = this;

    this.each( function ( i ) {
        $.fn.dataTableExt.iApiIndex = i;
        var
            $this = this, 
            oTimerId = null, 
            sPreviousSearch = null,
            anControl = $( 'input', _that.fnSettings().aanFeatures.f );

            anControl
              .unbind( 'keyup' )
              .bind( 'keyup', function(e) {

              if ( anControl.val().length > 2 && e.keyCode == 13){
                _that.fnFilter( anControl.val() );
              }
        });

        return this;
    } );
    return this;
}

使用方法:

$('#table').dataTable().fnSetFilteringEnterPress();

你不想要“如果长度大于2 按下回车键吗? if (anControl.val().length > 2 || e.keyCode == 13) - Jeromy French
是的,那也可以。我只是更专注于验证方面,即使传递了空字符串并按下了回车键,也不会发生任何事情。 - Christian Noel

5

之前的解决方法都不能满足我的需求,所以我制作了这个修改版,还加入了去抖动功能。与所有最新版本完美兼容。

您可以轻松更改或删除最小字符限制和去抖时间值。

jQuery(document).on( 'init.dt', function (e, settings) {
  var dti = jQuery('.dataTables_filter input');
  var api = new jQuery.fn.dataTable.Api( settings );
  var dbn = null;

  dti.off().on('input', function(e) {
    clearTimeout( dbn );
    var str = this.value;
    dbn = setTimeout(function(){
      if(str.length > 2 || e.keyCode == 13) api.search( str ).draw();
      if(str == '') api.search( '' ).draw();
    }, 300);
    return;
  });
});

3

对于1.10版本,在选项中将以下代码添加到您的JavaScript中。 initComplete覆盖了搜索方法,并等待输入3个字符。 感谢http://webteamalpha.com/triggering-datatables-to-search-only-on-enter-key-press/给了我启示。

    var dtable= $('#example').DataTable( {
        "deferRender": true,
        "processing": true,
        "serverSide": true,


        "ajax": "get_data.php",
        "initComplete": function() {
            var $searchInput = $('div.dataTables_filter input');

            $searchInput.unbind();

            $searchInput.bind('keyup', function(e) {
                if(this.value.length > 3) {
                    dtable.search( this.value ).draw();
                }
            });
        }

    } );
} );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接