jQuery DataTables: задержка поиска до тех пор, пока не будет набрано 3 символа или нажата кнопка



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



Я написал PHP-скрипт для коллег, отображающий 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'
}
} );
467   19  

19 ответов:

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

Примечание: это было для гораздо более ранней версии таблиц данных, пожалуйста, смотрите ответ для 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 привязаны к обоим keypress и keyup, но я переопределяю оба из них, чтобы оставаться совместимыми, хотя я думаю, что keyup достаточно.

надеюсь, что это помогает!

почему бы не попробовать эту расширенную версию ответа Стоуни:)

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

});

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

надеюсь, что это помогает.

вот как справиться с изменением 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;
});

вот плагин, как скрипт, который расширяет таблицы данных.

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

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

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

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

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 переопределяет метод поиска и ждать до 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();
                }
            });
        }

    } );
} );

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

вы можете задержать вызов 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 и только при прекращении ввода. Вы можете "играть" с задержкой param (300) для того, чтобы получить более или менее задержки

моя версия datatables 1.10.10

Я немного изменил вещи, и теперь это работает. Итак, я делюсь, потому что было трудно заставить его работать для версии 1.10.10. Благодаря cale_b, каменистые и Сэм Барнс. Посмотрите на код, чтобы увидеть, что я сделал.

    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 символов, используйте задержку, так что поиск начинается, как только они перестали печатать на 1 секунду или около того.

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

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

вы можете получить длину данных, которые передаются в использование данных.currentTarget.значение.длина, см. ниже.

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

исправлена версия для datatables 1.10.12 с помощью API и правильно развязать "вход". Также добавлен поиск clear на backspace под лимитом символов.

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

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

что-то вроде:

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

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

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

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

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

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

вам нужно изменить jquery.таблицы данных.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 будут уменьшены.

Comments

    Ничего не найдено.