jQuery DataTables:延迟search,直到键入3个字符或点击一个button

请input3个字符后才能开始search?

我为同事们写了一个PHP脚本,显示了两万个条目,他们抱怨说,当input一个单词时,前几个字母会导致一切冻结。

另一种方法是通过点击button启动search,而不是通过字符input。

以下是我目前的代码:

$("#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": "&lt;&lt;", "sLast": "&gt;&gt;", "sNext": "&gt;", "sPrevious": "&lt;" }, "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' } } ); 

解决scheme版本1.10 –

在这里寻找完整的答案,而不是find一个,我写了这个(利用从文档的代码,并在这里几个答案)。

以下代码可用于延迟search,直到至lessinput3个字符:

 // 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; }); 

注意:这是数据表的更早版本,请参阅jQuery datatables v1.10和更高版本的答案 。


这将修改input框的行为,以便仅当返回被按下或search中至less有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的人都绑定到按键和键控,但我重写他们两个保持兼容,但我认为键盘是足够的。

希望这可以帮助!

为什么不试试这个扩展版本的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); }); 

这将延迟search,直到用户停止键入。

希望能帮助到你。

这里是如何处理它与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; }); 

这是一个扩展数据表的插件式脚本。

 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(); 

要做的是在用户在search框中键入最小字符后调用服务器调用,可以按照艾伦的build议 :

定制fnSetFilteringDelay()插件API函数 ,在设置filter之前在string长度上添加一个额外的条件,同样考虑一个空stringinput来清除filter

因此,至less3个字符,只需将插件中的第19行更改为:

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

这适用于DataTables 10.0.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

用这个

  "fnServerData": function (sSource, aoData, fnCallback, oSettings) { if ($("#myDataTable_filter input").val() !== "" && $("#myDataTable_filter input").val().length < 3) return; oSettings.jqXHR = $.ajax({ "dataType": 'json', "timeout":12000, "type": "POST", "url": sSource, "data": aoData, "success": fnCallback }); } 

为1.10版本添加此代码到您的JavaScript的选项。 initComplete覆盖search方法并等待写入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(); } }); } } ); } ); 

虽然它没有回答原来的问题,但是我对数据表进行了一个复杂而慢的search。 filter事件在每次按键后都会触发,这意味着10个字符之后的延迟非常明显。 所以通过在filter事件被触发之前在按键之后引入一个短暂的延迟,在随后的按键复位计数器并阻止先前的search的情况下,我能够使search看起来更快。 别人可能会觉得这很有帮助

我用石质和基督教诺埃尔的答案来做到这一点:

 var dataTableFilterTimeout; var dataTableFilterWait = 200; // number of milliseconds to wait before firing filter $.fn.dataTableExt.oApi.fnSetFilteringEnterPress = function ( oSettings ) { var _that = this; this.each( function ( i ) { $.fn.dataTableExt.iApiIndex = i; var $this = this; var oTimerId = null; var sPreviousSearch = null; anControl = $( 'input', _that.fnSettings().aanFeatures.f ); anControl.unbind( 'keyup' ).bind( 'keyup', function(e) { window.clearTimeout(dataTableFilterTimeout); if ( anControl.val().length > 2 || e.keyCode == 13){ dataTableFilterTimeout = setTimeout(function(){ _that.fnFilter( anControl.val() ); },dataTableFilterWait); } }); return this; } ); return this; } 

你可以通过这个延迟ajax调用服务器

 var search_thread = null; $(".dataTables_filter input") .unbind() .bind("input", function(e) { clearTimeout(search_thread); search_thread = setTimeout(function(){ var dtable = $("#list_table").dataTable().api(); var elem = $(".dataTables_filter input"); return dtable.search($(elem).val()).draw(); }, 300); }); 

如果按键之间的时间less于300毫秒,这段代码将停止ajax调用,这样,当你写一个字时,只有一个ajax调用会运行,只有当你停止input。 你可以用延迟参数(300)“玩”,以获得或多或less的延迟

我的数据表版本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); }); 

你可能不得不修改插件。

而不是使它X个字符,使用延迟,所以search开始,一旦停止键入1秒左右。

所以当前触发search的keydown / keyup绑定会被一个定时器修改。

 var timer; clearTimeout(timer); timer = setTimeout(searchFunctionName, 1000 /* timeToWaitInMS */); 

您可以使用data.currentTarget.value.length获取正在传入的数据的长度,请参阅下面的内容。

 $('[id$="Search"]').keyup(function (data) { if (data.currentTarget.value.length > 2 || data.currentTarget.value.length == 0) { if (timoutOut) { clearTimeout(timoutOut); } timoutOut = setTimeout(function () { var value = $('[id$="Search"]').val(); $('#jstree').jstree(true).search(value); }, 250); } }); 

显然你会希望这段代码在删除文本时运行,所以将值设置为0

你可以编写自己的函数来testing附加到onKeyUp事件处理程序的inputstring的长度,并在达到最小长度后触发searchfunction?

有些东西是:

 input.onKeyUp(function(){
     if(input.length> 3){
         mySearchfunction();
     }
 });

也就是说,用伪代码的方式,但你得到了jist。

您可以使用名称minlength的参数,以限制search,直到3个字符:

 function(request, response) { $.getJSON("/speakers/autocomplete", { q: $('#keywordSearch').val() }, response); }, minLength: 3 

是否有一个原因,你不会只是检查“变化”的长度?

 $('.input').change(function() { if( $('.input').length > 3 ) { //do the search } }); 

你需要修改jquery.datatables.js

—–更新的课程,你可以检查长度> 3,但我认为你仍然需要一个计时器。 如果你有很多的数据,你不希望在每次更新字符后都得到过滤。

在这个方法中:

 jqFilter.keyup( function(e) { if ( **this.value**.length > 3) { var n = oSettings.aanFeatures.f; for ( var i=0, iLen=n.length ; i<iLen ; i++ ) { if ( n[i] != this.parentNode ) { $('input', n[i]).val( this.value ); } } /* Now do the filter */ _fnFilterComplete( oSettings, { "sSearch": this.value, "bRegex": oSettings.oPreviousSearch.bRegex, "bSmart": oSettings.oPreviousSearch.bSmart } ); } } ); 

给keyup添加一个定时器,如其中一个答案所示。

然后去这个网站http://jscompress.com/

而过去你的修改过的代码和JS会被缩小。