可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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'
}
} );
回答1:
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;
});
回答2:
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!
回答3:
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.
回答4:
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;
});
回答5:
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();
回答6:
To do is 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())) {
回答7:
This works on 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
回答8:
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
});
}
回答9:
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();
}
});
}
} );
} );
回答10:
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;
}
回答11:
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
回答12:
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);
});
回答13:
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 */);
回答14:
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
回答15:
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();
}
});
回答16:
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.
回答17:
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
回答18:
Is there a reason you wouldn't just check length on 'change'?
$('.input').change(function() {
if( $('.input').length > 3 ) {
//do the search
}
});
回答19:
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.