jQuery DataTables:延迟搜索,直到输入 3 个字符或单击按钮

发布于 2024-10-30 21:34:41 字数 1924 浏览 6 评论 0原文

有没有一个选项可以在输入 3 个字符后才开始搜索?

我为同事编写了一个显示 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'
        }
} );

Is there please an option to start the search only after 3 characters have been typed in?

I have written a PHP-script for colleagues displaying 20,000 entries and they complain, that when typing a word, the first few letters cause everything to freeze.

An alternative would be to have the search to be started by a button clicked and not by character typing.

Below is my current code:

$("#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'
        }
} );

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(24

嘦怹 2024-11-06 21:34:42

用这个

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

Use this

   "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
            });
        }
佼人 2024-11-06 21:34:42

尽管它没有回答最初的问题,但我对数据表进行了复杂而缓慢的搜索。每次按键后都会触发过滤器事件,这意味着 10 个字符后会出现相当明显的延迟。因此,通过在触发过滤事件之前在按键后引入短暂的延迟,随后的按键会重置计数器并阻止之前的搜索,我能够使搜索看起来更快。其他人可能会发现这很有帮助。

我用斯托尼和克里斯蒂安·诺埃尔的答案来做到这一点:

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

although it does not answer the original question, i had a complex and slow search on my datatables. the filter event was firing after each keypress, which meant a quite noticeable delay after 10 characters. so by introducing a short delay after a keypress before the filter event was fired, where a subsequent keypress reset the counter and prevented the previous search, i was able to make the search seem much faster. others may find this helpful.

i used the answers from stony and christian noel to make this:

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;
}
荆棘i 2024-11-06 21:34:42

你可以通过这个延迟对服务器的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);
        });

如果按键之间的时间小于300毫秒,这段代码将停止ajax调用,这样当你写一个单词时,只有一个ajax调用会运行,并且只有当你停止打字。
您可以使用延迟参数(300)来“玩”以获得更多或更少的延迟

You can delay the ajax call to the server by this

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

This code will stop the ajax call if the time between to key press is less then 300 ms, in that way when you write a word, only one ajax call will run and only when you stop typing.
You can 'play' with the delay param ( the 300) in order to get more or less delay

灯角 2024-11-06 21:34:42

对于 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();
                }
            });
        }

    } );
} );

for 1.10 version add this code to your javascript in the options.
The initComplete overrides the search method and wait to 3 characters are written.
Thanks to http://webteamalpha.com/triggering-datatables-to-search-only-on-enter-key-press/ for giving me the light.

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

    } );
} );
无人接听 2024-11-06 21:34:42

您可能需要修改该插件。

不要使用 X 个字符,而是使用延迟,这样一旦他们停止输入 1 秒左右,搜索就会开始。

因此,当前触发搜索的 keydown/keyup 绑定将使用计时器进行修改......

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

You'll probably have to modify the plugin.

And instead of making it X characters, use a delay, so the search starts once they stopped typing for 1 second or so.

So the keydown/keyup binding which is currently triggering the search would be modified with a timer...

var timer;
clearTimeout(timer);
timer = setTimeout(searchFunctionName, 1000 /* timeToWaitInMS */);
浅浅淡淡 2024-11-06 21:34:42

您可以使用 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

You can get the length of the data that is being passed in using data.currentTarget.value.length, please see below.

$('[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);
            }
        });

and obviously you would want this code to run when removing text so set the value to 0

浊酒尽余欢 2024-11-06 21:34:42

使用 API 并正确解除绑定“输入”的数据表 1.10.12 的修复版本。还添加了字符限制下的退格搜索清除功能。

    // Create the Datatable
    var pTable = $('#pTable').DataTable();

    // Get the Datatable input box and alter events
    $('.dataTables_filter input')
    .unbind('keypress keyup input')
    .bind('keypress keyup input', function (e) {
        if ($(this).val().length > 2) {
            pTable.search(this.value).draw();
        } else if (($(this).val().length == 2) && (e.keyCode == 8)) {
            pTable.search('').draw();
        }
    });

Fixed version for datatables 1.10.12 using API and correctly unbinding the 'input'. Also added search clear on backspace under the character limit.

    // Create the Datatable
    var pTable = $('#pTable').DataTable();

    // Get the Datatable input box and alter events
    $('.dataTables_filter input')
    .unbind('keypress keyup input')
    .bind('keypress keyup input', function (e) {
        if ($(this).val().length > 2) {
            pTable.search(this.value).draw();
        } else if (($(this).val().length == 2) && (e.keyCode == 8)) {
            pTable.search('').draw();
        }
    });
晌融 2024-11-06 21:34:42

如果您使用的是旧版本,看起来就像这样。理查德的解决方案效果很好。
但是当我使用它时,我只是添加了新事件,而不是删除。因为当代码运行时,表还没有创建。
所以我发现有 fnInitComplete 方法(创建表时触发),并将其应用于 Ricard 的解决方案。
这里是

$("#my_table").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "bAutoWidth": false,
         ...
         ...,
         "fnInitComplete": function (oSettings, json) {
                    var activeDataTable = $(this).DataTable();
                    $("#my_table_filter input")
                        .unbind('keypress keyup')
                        .bind('keypress keyup', function (e) {

                        if ($(this).val().length < 3 || e.keyCode !== 13) return;
                        activeDataTable.fnFilter($(this).val());
                    });
                }

If you're using the old version, it looks like it. Richard's solution works fine.
But when I use it, I just added new events, not deleting. Because when code run, table is not yet created.
So I found that there is the fnInitComplete method (fire when table created) and I applied it to Ricard's solution.
Here it is

$("#my_table").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "bAutoWidth": false,
         ...
         ...,
         "fnInitComplete": function (oSettings, json) {
                    var activeDataTable = $(this).DataTable();
                    $("#my_table_filter input")
                        .unbind('keypress keyup')
                        .bind('keypress keyup', function (e) {

                        if ($(this).val().length < 3 || e.keyCode !== 13) return;
                        activeDataTable.fnFilter($(this).val());
                    });
                }
苏别ゝ 2024-11-06 21:34:42

您可以编写自己的函数来测试附加到 onKeyUp 事件处理程序的输入字符串的长度,并在达到最小长度后触发搜索函数吗?

大致如下:

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

...也就是说,以伪代码的方式,但你明白了要点。

Can you write your own function to test for the length of the inputed string attached to an onKeyUp event handler and trigger the search function once the min length has been reached?

Something along the lines of:

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

...that is, in a pseudo code kind of way but you get the jist.

So要识趣 2024-11-06 21:34:42

您可以使用名称 minlength 参数来将搜索限制为 3 个字符:

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

You can use the parameter by name minlength in order to restrict the search until 3 characters:

function(request, response) {
    $.getJSON("/speakers/autocomplete", {  
        q: $('#keywordSearch').val()
    }, response);
}, minLength: 3
甜是你 2024-11-06 21:34:42

这里的大多数答案都以某种方式操纵现有的 DataTable 事件绑定,但就我个人而言,在花费了太长时间试图使其工作后,我最终发现最好的方法是在 search< 中发送一个虚拟值ajax 调用期间的 /code> 参数。

// ... denotes expected code for DataTable to function excluded for clarity.
$("#example").dataTable({
  ...
  'ajax': {
    ...
    'data': function (d) {
       d.search.value = d.search.value.length >= 3 ? d.search.value : "##EmptySearch##";
       return JSON.stringify(d);
    }
  }
});

##EmptySearch## 字符串只是充当一个不应该与任何返回的数据匹配的值(使用什么完全是个人喜好,但它应该是一个保证不与任何数据匹配的字符串)。由于尚未对绑定进行操作,所以所有常用功能仍然有效,但在搜索大于或等于三个字符之前不会返回任何有意义的内容。诚然,这并不理想,宁愿根本不发出服务器请求,但这是(在我看来)最简单的方法,不会破坏数据表搜索的现有功能。

Most of the answers here in some way manipulate the existing DataTable event bindings but personally after spending far too long trying to get this working the best approach I found, in the end, was to just send a dummy value in the search parameter during the ajax call.

// ... denotes expected code for DataTable to function excluded for clarity.
$("#example").dataTable({
  ...
  'ajax': {
    ...
    'data': function (d) {
       d.search.value = d.search.value.length >= 3 ? d.search.value : "##EmptySearch##";
       return JSON.stringify(d);
    }
  }
});

The ##EmptySearch## string simply acts as a value that shouldn't match any returned data (it's entirely personal preference what to use, but it should be a string that is guaranteed to not match any data). Because the bindings have not been manipulated all the usual bells and whistles still work but nothing meaningful is returned until the search is greater than or equal to three characters. Admittedly it isn't ideal, would prefer to not make the server request at all but this is (in my opinion) the simplest approach that doesn't ruin the existing functionality of the DataTable search.

往昔成烟 2024-11-06 21:34:42

需要修改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 将被缩小。

You need to modify the jquery.datatables.js

----- updated
ofcourse you can do a check on lenght > 3, but I think you still need a timer. if you have a lot of data, you don't want to keep getting it filtered after every character update.

Within this method:

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

Add a timer to the keyup, like shown in one of the answers.

Then go to this site http://jscompress.com/

And past your modified code and the js wil get minified.

℡Ms空城旧梦 2024-11-06 21:34:42

您可以在 Medtronic 数据表或其他代码上使用此代码在使用 3 个字符后进行搜索:

        onDataLoad: function (RequestGrid) {
            // execute some code on ajax data load
            var searchInput = $('div.dataTables_filter input').val();
            if (searchInput.length() > 3 || searchInput.length() ==0) {
                alert(searchInput);
                dt.draw();
            }
            else {
                return false;
            }
        },

searchInput.length() ==0 首次显示。

You can use this code on Medtronic datatable or other code to search after using 3 character :

        onDataLoad: function (RequestGrid) {
            // execute some code on ajax data load
            var searchInput = $('div.dataTables_filter input').val();
            if (searchInput.length() > 3 || searchInput.length() ==0) {
                alert(searchInput);
                dt.draw();
            }
            else {
                return false;
            }
        },

searchInput.length() ==0 for first show.

笑咖 2024-11-06 21:34:42

这适用于 DataTables 版本 1.10.19。它只需要在您的网站模板中包含 js - 对于在不同页面上配置了多个数据表的网站非常有用。对于任何缓慢的 xhr 加载表也很有用,在所有当前运行完成之前不会允许任何新的 xhr 请求。使用的搜索功能与插件设置 搜索功能本来。

(function(window, document, $){
var xhring = 0;

$(document).on( 'preXhr.dt', function () {
    xhring++;
} );
$(document).on( 'xhr.dt', function () {
    xhring--;
} );

//at a minimum wait the full freq, and wait for any pending XHR requests to finish before calling fn
function choke( fn, freq ) {
    var
        frequency = freq !== undefined ? freq : 200,
        last,
        timerFn,
        timer;

    return function () {
        var
            that = this,
            args = arguments;

        timerFn = function () {
            if (xhring || +new Date() < last + frequency) {
                clearTimeout( timer );
                timer = setTimeout( timerFn, frequency);
            } else {
                fn.apply( that, args );
            }
        }
        last = +new Date();

        clearTimeout( timer );
        timer = setTimeout( timerFn, frequency );
    };
}

//See https://github.com/DataTables/DataTables/blob/156faa83386460c578e00c460eca9766e38a0c5f/media/js/jquery.dataTables.js
//See https://github.com/DataTables/Plugins/blob/master/features/searchHighlight/dataTables.searchHighlight.js
$(document).on( 'preInit.dt', function (e, settings, json) {
    var previousSearch = settings.oPreviousSearch;

    var searchFn = function() {
        /* Update all other filter input elements for the new display */
        var val = !this.value ? "" : this.value; // mental IE8 fix :-(

        /* Now do the filter */                                                                                                  
        if ( val != previousSearch.sSearch && (val.length >= 3 || val == "")) {
            $.fn.dataTable.ext.internal._fnFilterComplete( settings, {
                "sSearch": val,
                "bRegex": previousSearch.bRegex,
                "bSmart": previousSearch.bSmart ,
                "bCaseInsensitive": previousSearch.bCaseInsensitive
            } );

            // Need to redraw, without resorting
            settings._iDisplayStart = 0;
            $.fn.dataTable.ext.internal._fnDraw( settings );
        }
    };

    var searchDelay = settings.searchDelay !== null ?                                                                            
        settings.searchDelay :
        $.fn.dataTable.ext.internal._fnDataSource( settings ) === 'ssp' ?
            700 :
            200;

    var jqFilter = $( 'input', settings.aanFeatures.f )
        .off('keyup.DT search.DT input.DT paste.DT cut.DT')
        .on('keyup.DT search.DT input.DT paste.DT cut.DT', choke(searchFn, searchDelay))
        ;
} );

})(window, document, jQuery);

This works with DataTables version 1.10.19. It only requires including the js in your website template - useful for a site that has multiple dataTables configured on different pages. Also useful for any slow xhr loading tables, will not allow any new xhr requests until all currently running finish. The search function used is very similar to how the plugin sets up the search function originally.

(function(window, document, $){
var xhring = 0;

$(document).on( 'preXhr.dt', function () {
    xhring++;
} );
$(document).on( 'xhr.dt', function () {
    xhring--;
} );

//at a minimum wait the full freq, and wait for any pending XHR requests to finish before calling fn
function choke( fn, freq ) {
    var
        frequency = freq !== undefined ? freq : 200,
        last,
        timerFn,
        timer;

    return function () {
        var
            that = this,
            args = arguments;

        timerFn = function () {
            if (xhring || +new Date() < last + frequency) {
                clearTimeout( timer );
                timer = setTimeout( timerFn, frequency);
            } else {
                fn.apply( that, args );
            }
        }
        last = +new Date();

        clearTimeout( timer );
        timer = setTimeout( timerFn, frequency );
    };
}

//See https://github.com/DataTables/DataTables/blob/156faa83386460c578e00c460eca9766e38a0c5f/media/js/jquery.dataTables.js
//See https://github.com/DataTables/Plugins/blob/master/features/searchHighlight/dataTables.searchHighlight.js
$(document).on( 'preInit.dt', function (e, settings, json) {
    var previousSearch = settings.oPreviousSearch;

    var searchFn = function() {
        /* Update all other filter input elements for the new display */
        var val = !this.value ? "" : this.value; // mental IE8 fix :-(

        /* Now do the filter */                                                                                                  
        if ( val != previousSearch.sSearch && (val.length >= 3 || val == "")) {
            $.fn.dataTable.ext.internal._fnFilterComplete( settings, {
                "sSearch": val,
                "bRegex": previousSearch.bRegex,
                "bSmart": previousSearch.bSmart ,
                "bCaseInsensitive": previousSearch.bCaseInsensitive
            } );

            // Need to redraw, without resorting
            settings._iDisplayStart = 0;
            $.fn.dataTable.ext.internal._fnDraw( settings );
        }
    };

    var searchDelay = settings.searchDelay !== null ?                                                                            
        settings.searchDelay :
        $.fn.dataTable.ext.internal._fnDataSource( settings ) === 'ssp' ?
            700 :
            200;

    var jqFilter = $( 'input', settings.aanFeatures.f )
        .off('keyup.DT search.DT input.DT paste.DT cut.DT')
        .on('keyup.DT search.DT input.DT paste.DT cut.DT', choke(searchFn, searchDelay))
        ;
} );

})(window, document, jQuery);
合约呢 2024-11-06 21:34:42

您是否有理由不只检查“更改”的长度?

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

Is there a reason you wouldn't just check length on 'change'?

$('.input').change(function() {
  if( $('.input').length > 3 ) {
     //do the search
  }
});
你是我的挚爱i 2024-11-06 21:34:41

版本 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;
    });

Solution for version 1.10 -

After looking here for a complete answer and not finding one, I've written this (utilizing code from the documentation, and a few answers here).

The below code works to delay searching until at least 3 characters are entered:

// 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;
    });
红颜悴 2024-11-06 21:34:41

注意:这是针对早期版本的数据表,请参阅 jQuery 数据表 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 就足够了。

希望这有帮助!

Note: This was for a much earlier version of data tables, please see this answer for jQuery datatables v1.10 and above.


This will modify the behaviour of the input box to only filter when either return has been pressed or there are at least 3 characters in the search:

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

You can see it working here: http://jsbin.com/umuvu4/2. I don't know why the dataTables folks are binding to both keypress and keyup, but I'm overriding both of them to stay compatible although I think keyup is sufficient.

Hope this helps!

ヅ她的身影、若隐若现 2024-11-06 21:34:41

为什么不尝试 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);

});

这会延迟搜索,直到用户停止打字。

希望有帮助。

Why not try this extended version of Stony's answer :)

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

});

This will delay the search until the user has stopped typing.

Hope it helps.

樱娆 2024-11-06 21:34:41

这是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;
});

Here is how to handle it with the api change in version 1.10

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;
});
腹黑女流氓 2024-11-06 21:34:41

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

    });

My version of datatables 1.10.10

I changed a little things and it works now. So, i'm sharing, cause it was difficulty to make it work for version 1.10.10. Thanks to cale_b, Stony and Sam Barnes. Look at the code to see what i did.

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

    });
流殇 2024-11-06 21:34:41

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

This works on 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

何以畏孤独 2024-11-06 21:34:41

要在用户在搜索框中键入最少字符后调用服务器调用,您可以遵循 艾伦的建议

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


因此,对于至少 3 个字符,只需更改 插件

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

To invoke the server call after the user has typed the mininum characters in the search box, you can follow Allan's suggestion:

customize the fnSetFilteringDelay() plug-in API function to add
an extra condition on the string length before setting the filter, also
considering a blank string input to clear the filter

So for a minimum of 3 characters, just change line #19 in the plug-in to:

if ((anControl.val().length == 0 || anControl.val().length >= 3) && (sPreviousSearch === null || sPreviousSearch != anControl.val())) {
东走西顾 2024-11-06 21:34:41

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

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

Here's a plugin-like script that extends datatables.

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

usage:

$('#table').dataTable().fnSetFilteringEnterPress();
怎会甘心 2024-11-06 21:34:41

以前的解决方案都不适合我,所以我制作了这个修改版本,还添加了去抖功能。与所有最新版本完美配合。

您可以简单地更改或删除最小字符限制和去抖超时值。

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

None of the previous solutions worked for me so I have made this modified version that also adds a debounce. Working perfectly with all the latest versions.

You can simply change or remove the min character limit and debounce timeout value.

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;
  });
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文