Czy istnieje możliwość rozpoczęcia wyszukiwania dopiero po wpisaniu 3 znaków?
Napisałem skrypt PHP dla kolegów wyświetlających 20 000 wpisów i narzekają, że przy wpisywaniu słowa pierwsze kilka liter powoduje zawieszenie się wszystkiego.
Alternatywą byłoby rozpoczęcie wyszukiwania kliknięciem przycisku, a nie wpisywaniem znaków.
Poniżej znajduje się mój aktualny kod:
$("#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'
}
} );
jquery
datatables
Alexander Farber
źródło
źródło
init.dt
przypadku, np$('#yourTable').on('init.dt', function () { ... });
.Uwaga: dotyczyło to znacznie wcześniejszej wersji tabel danych, zobacz tę odpowiedź dla danych jQuery w wersji 1.10 i nowszych.
Spowoduje to zmianę zachowania pola wejściowego, aby filtrować tylko po naciśnięciu klawisza return lub w wyszukiwaniu są co najmniej 3 znaki:
$(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()); }); });
Możesz zobaczyć, jak działa tutaj: http://jsbin.com/umuvu4/2 . Nie wiem, dlaczego ludzie z dataTables wiążą się zarówno z klawiszem, jak i klawiszem, ale nadpisuję oba z nich, aby zachować zgodność, chociaż myślę, że kluczowanie jest wystarczające.
Mam nadzieję że to pomoże!
źródło
e.keycode != 13
jee.keyCode > 13
, które również będą uruchamiane, gdy wyjdą z pola..unbind('keypress keyup') .bind('keypress', function(e) ...
Dlaczego nie wypróbować tej rozszerzonej wersji odpowiedzi Stony'ego :)
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); });
Spowoduje to opóźnienie wyszukiwania do momentu, gdy użytkownik przestanie pisać.
Mam nadzieję, że to pomoże.
źródło
setTimeout(function(){...}, 600)
, ponieważ funkcja nie wydaje się być ponownie uruchamiana na kolejnych znakach.setInterval
, ponieważ jest odświeżane co 200/600 ms i sprawdza, czy funkcja searchWait nie została zresetowana do 0. np. jeśli nadal będziesz wprowadzać coś do wejścia, zawsze zresetujesz searchWait do 0 = wyszukiwanie nigdy nie jest wykonywane. Uważam jednak, że użycie searchWait jako liczby całkowitej, która liczy do 3, jest raczej niejasne. Lepiej byłoby po prostu prawdziwą / fałszywą flagą, gdyby nastąpiło wejście użytkownika isetInterval
600.Oto jak sobie z tym poradzić ze zmianą interfejsu API w wersji 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; });
źródło
Moja wersja danych 1.10.10
Zmieniłem trochę rzeczy i teraz działa. Więc udostępniam, ponieważ trudno było sprawić, by działało w wersji 1.10.10. Dzięki cale_b, Stony i Sam Barnes. Spójrz na kod, aby zobaczyć, co zrobiłem.
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); });
źródło
Oto skrypt podobny do wtyczki, który rozszerza dane.
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; }
stosowanie:
$('#table').dataTable().fnSetFilteringEnterPress();
źródło
if ( anControl.val().length > 2 || e.keyCode == 13)
Aby to zrobić, wywołać wywołanie serwera po wpisaniu przez użytkownika minimalnych znaków w polu wyszukiwania, możesz postępować zgodnie z sugestią Allana :
Więc dla minimum 3 znaków, po prostu zmień wiersz nr 19 we wtyczce na:
if ((anControl.val().length == 0 || anControl.val().length >= 3) && (sPreviousSearch === null || sPreviousSearch != anControl.val())) {
źródło
Działa to w 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
źródło
dla wersji 1.10 dodaj ten kod do swojego javascript w opcjach. InitComplete zastępuje metodę wyszukiwania i czeka na zapisanie 3 znaków. Podziękowania dla http://webteamalpha.com/triggering-datatables-to-search-only-on-enter-key-press/ za danie mi światła.
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(); } }); } } ); } );
źródło
Użyj tego
"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 }); }
źródło
chociaż nie odpowiada na pierwotne pytanie, przeszedłem złożone i powolne wyszukiwanie w moich plikach danych. zdarzenie filtra było uruchamiane po każdym naciśnięciu klawisza, co oznaczało dość zauważalne opóźnienie po 10 znakach. więc wprowadzając krótkie opóźnienie po naciśnięciu klawisza przed uruchomieniem zdarzenia filtrującego, w którym kolejne naciśnięcie klawisza resetuje licznik i uniemożliwia poprzednie wyszukiwanie, udało mi się sprawić, że wyszukiwanie wydawało się znacznie szybsze. inni mogą uznać to za pomocne.
Użyłem odpowiedzi Stony and Christian Noel, aby to zrobić:
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; }
źródło
Możesz przez to opóźnić wywołanie AJAX do serwera
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); });
Ten kod zatrzyma wywołanie Ajax, jeśli czas między naciśnięciem klawisza jest krótszy niż 300 ms, w ten sposób, gdy napiszesz słowo, uruchomi się tylko jedno wywołanie Ajax i tylko wtedy, gdy przestaniesz pisać. Możesz „grać” z parametrem opóźnienia (300), aby uzyskać mniej lub więcej opóźnienia
źródło
Prawdopodobnie będziesz musiał zmodyfikować wtyczkę.
Zamiast tworzyć X znaków, użyj opóźnienia, więc wyszukiwanie rozpocznie się, gdy przestaną pisać na 1 sekundę.
Tak więc powiązanie keydown / keyup, które obecnie uruchamia wyszukiwanie, zostanie zmodyfikowane za pomocą timera ...
var timer; clearTimeout(timer); timer = setTimeout(searchFunctionName, 1000 /* timeToWaitInMS */);
źródło
Poprawiona wersja dla danych 1.10.12 wykorzystująca API i poprawne rozpinanie 'wejścia'. Dodano również jasne wyszukiwanie w backspace poniżej limitu znaków.
// 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(); } });
źródło
Jeśli używasz starej wersji, wygląda na to. Rozwiązanie Richarda działa dobrze. Ale kiedy go używam, po prostu dodałem nowe wydarzenia, nie usuwając. Ponieważ po uruchomieniu kodu tabela nie jest jeszcze utworzona. Odkryłem więc, że istnieje metoda fnInitComplete (uruchamiaj po utworzeniu tabeli) i zastosowałem ją do rozwiązania Ricarda. Tutaj jest
$("#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()); }); }
źródło
Możesz użyć tego kodu w bazie danych Medtronic lub innym kodzie do wyszukiwania po użyciu 3 znaków:
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 dla pierwszego pokazu.
źródło
Czy możesz napisać własną funkcję do testowania długości wprowadzonego ciągu dołączonego do procedury obsługi zdarzeń onKeyUp i wyzwolić funkcję wyszukiwania po osiągnięciu minimalnej długości?
Coś w rodzaju:
... to znaczy w formie pseudokodu, ale masz jist.
źródło
Możesz użyć parametru według nazwy minlength, aby ograniczyć wyszukiwanie do 3 znaków:
function(request, response) { $.getJSON("/speakers/autocomplete", { q: $('#keywordSearch').val() }, response); }, minLength: 3
źródło
Długość przekazywanych danych można uzyskać za pomocą parametru data.currentTarget.value.length, patrz poniżej.
$('[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); } });
i oczywiście chciałbyś, aby ten kod działał podczas usuwania tekstu, więc ustaw wartość na 0
źródło
Działa to z DataTables w wersji 1.10.19. Wymaga tylko włączenia js do szablonu witryny - przydatne w przypadku witryny, która ma wiele dataTables skonfigurowanych na różnych stronach. Przydatne również dla dowolnych wolno ładujących się tabel xhr, nie zezwala na żadne nowe żądania xhr, dopóki wszystkie aktualnie uruchomione nie zostaną zakończone. Funkcja wyszukiwania używany jest bardzo podobny do tego, jak Wtyczka ustawia funkcję wyszukiwania pierwotnie.
(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);
źródło
Czy jest jakiś powód, dla którego nie sprawdzałeś długości po prostu po „zmianie”?
$('.input').change(function() { if( $('.input').length > 3 ) { //do the search } });
źródło
Musisz zmodyfikować plik jquery.datatables.js
----- zaktualizowano oczywiście możesz sprawdzić długość> 3, ale myślę, że nadal potrzebujesz timera. jeśli masz dużo danych, nie chcesz filtrować ich po każdej aktualizacji postaci.
W ramach tej metody:
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 } ); } } );
Dodaj licznik czasu do klucza, jak pokazano w jednej z odpowiedzi.
Następnie przejdź do tej witryny http://jscompress.com/
Po przejściu zmodyfikowanego kodu plik js zostanie zminimalizowany.
źródło