JQuery DataTables: поиск задержки до ввода 3 символов ИЛИ нажатие на кнопку

Есть ли возможность начать поиск только после ввода трех символов?

Я написал PHP- script для коллег, отображающих 20 000 записей, и они жалуются, что при вводе слова первые несколько букв заставляют все замораживать.

Альтернативой может быть поиск, который будет запускаться нажатием кнопки, а не путем ввода символов.

Ниже мой текущий код:

$("#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

Решение для версии 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;
    });

Ответ 2

Примечание: это было для намного более ранней версии таблиц данных, пожалуйста, смотрите этот ответ для jQuery datatables v1.10 и выше.


Это изменит поведение поля ввода так, чтобы оно фильтровалось только тогда, когда нажата клавиша return или в поиске есть хотя бы 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 связывают и нажатие клавиш, и keyup, но я переопределяю их обоих, чтобы они оставались совместимыми, хотя я думаю, что keyup достаточно.

Надеюсь это поможет!

Ответ 3

Почему бы не попробовать эту расширенную версию ответа 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);

});

Это приведет к задержке поиска до тех пор, пока пользователь не перестанет печатать.

Надеюсь, что это поможет.

Ответ 4

Вот как обрабатывать его с изменением api в версии 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;
});

Ответ 5

Здесь есть плагин типа script, который расширяет данные.

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

Ответ 6

Чтобы сделать это, вызовите вызов сервера после того, как пользователь набрал мини-символы в поле поиска, вы можете следовать предложение Аллана:

настройте fnSetFilteringDelay() функцию API подключаемого модуля, чтобы добавить дополнительное условие на длину строки перед установкой фильтра, также учитывая пустой ввод строки для очистки фильтра

Итак, для минимум 3 символов просто измените строку # 19 в плагин до:

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

Ответ 7

Это работает на 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

Моя версия данных 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);

    });

Ответ 9

Используйте этот

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

Ответ 10

хотя он не отвечает на исходный вопрос, у меня был сложный и медленный поиск на моих данных. событие фильтра запускалось после каждого нажатия клавиши, что означало довольно заметную задержку после 10 символов. поэтому, введя небольшую задержку после нажатия клавиши перед запуском события фильтра, где последующее нажатие reset счетчика и предотвращение предыдущего поиска, я смог сделать поиск намного быстрее. другие могут найти это полезным.

Я использовал ответы от каменного и христианского ноэля, чтобы сделать это:

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

Ответ 11

Вы можете задержать вызов 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);
        });

Этот код остановит вызов ajax, если время между нажатиями клавиши меньше 300 мс, таким образом, когда вы пишете слово, будет запускаться только один вызов ajax и только когда вы перестанете печатать. Вы можете "играть" с параметром задержки (300), чтобы получить более или менее задержку

Ответ 12

для версии 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();
                }
            });
        }

    } );
} );

Ответ 13

Возможно, вам придется изменить плагин.

И вместо того, чтобы создавать буквы X, используйте задержку, поэтому поиск начинается, когда они перестали печатать в течение 1 секунды или около того.

Итак, привязка keydown/keyup, которая в настоящее время запускает поиск, будет изменена таймером...

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

Ответ 14

Вы можете получить длину данных, которые передаются с использованием 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

Ответ 15

Исправлена ​​версия для datatables 1.10.12 с использованием API и правильная развязка "ввода". Также добавлен поиск в обратном пространстве под лимитом.

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

Ответ 16

Если вы используете старую версию, это выглядит так. Решение Ричарда работает отлично. Но когда я его использую, я просто добавляю новые события, а не удаляю. Потому что при выполнении кода таблица еще не создана. Поэтому я обнаружил, что существует метод fnInitComplete (срабатывает при создании таблицы), и применил его к решению Рикара. Здесь это

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

Ответ 17

Можете ли вы написать свою собственную функцию для проверки длины введенной строки, прикрепленной к обработчику события onKeyUp, и запустить функцию поиска после достижения минимальной длины?

Что-то по строкам:

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

... то есть в псевдокоде, но вы получаете jist.

Ответ 18

Вы можете использовать параметр по имени minlength, чтобы ограничить поиск до трех символов:

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

Ответ 19

Есть ли причина, по которой вы не просто проверили бы длину на "change"?

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

Ответ 20

Вам нужно изменить 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 
                } );
         }
        } );

Добавьте таймер к клавиатуре, как показано в одном из ответов.

Затем перейдите на этот сайт http://jscompress.com/

И мимо вашего измененного кода и js wil получите minified.