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个回答

3

使用此功能

   "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 很好。这个很好地集成在数据表定义中。顺便说一下,在我的情况下,只返回aoData [5] ['value'] ['value'](输入字段中键入的文本)就足够了。 - Werner

3

虽然它没有回答原始问题,但我在我的数据表上进行了复杂而缓慢的搜索。过滤器事件在每次按键后触发,这意味着在输入10个字符后会有明显的延迟。所以,通过在按键后引入短暂的延迟,然后再触发过滤器事件,在随后的按键中重置计数器并防止之前的搜索,我能够使搜索看起来更快。其他人可能也会发现这很有用。

我使用了stony和christian noel的答案来制作这个:

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

3
你可以通过以下方式延迟向服务器发起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)来增加或减少延迟时间。


2
您可能需要修改插件。而不是设置X个字符,可以使用延迟,以便搜索在他们停止输入一秒钟左右后开始。因此,目前触发搜索的按键绑定将被修改为计时器...
var timer;
clearTimeout(timer);
timer = setTimeout(searchFunctionName, 1000 /* timeToWaitInMS */);

1
“修改插件”是指编辑jquery.dataTables.js吗?您知道如何在此之后进行“最小化”操作吗? - Alexander Farber

2

使用API修复了datatables 1.10.12版本的问题,并正确解除了“input”的绑定。在字符限制下还添加了按退格键清除搜索的功能。

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

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


2
如果你正在使用旧版本,它看起来像是这样。Richard的解决方案很好用。 但当我使用它时,我只是添加了新事件,而没有删除任何内容。因为在代码运行时,表格还没有被创建。 所以我发现有一个fnInitComplete方法(在表格创建时触发),并将其应用于Richard的解决方案。 以下是代码:
$("#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());
                    });
                }

1
你可以使用名为minlength的参数来限制搜索至少需要3个字符:
function(request, response) {
    $.getJSON("/speakers/autocomplete", {  
        q: $('#keywordSearch').val()
    }, response);
}, minLength: 3

1
大多数答案在某种程度上都是通过操作现有的DataTable事件绑定来实现的,但就我个人而言,在花费了太长时间尝试使其工作之后,最终发现的最佳方法是在ajax调用期间只发送一个虚拟值到search参数中。
// ... 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);
    }
  }
});
< p > ##EmptySearch## 字符串仅充当一个不应匹配任何返回数据的值(使用什么完全是个人喜好,但它应该是一个保证不匹配任何数据的字符串)。因为绑定没有被操作,所有通常的功能仍然有效,但在搜索大于或等于三个字符之前,没有返回任何有意义的数据。诚然这并不理想,我希望根本不需要进行服务器请求,但这是(在我看来)不会破坏DataTable搜索现有功能的最简单方法。


1
你能否编写自己的函数来测试附加到onKeyUp事件处理程序的输入字符串的长度,并在达到最小长度后触发搜索功能?
大致如下:
input.onKeyUp(function() {
    if(input.length > 3) {
        mySearchfunction();
    }
});
也就是说,这是一种伪代码方式,但你可以理解它的意思。

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