Server-side ajax search, wait till finish entering
Server-side ajax search, wait till finish entering
MrBaseball34
Posts: 96Questions: 0Answers: 0
I am using server-side processing and retrieval and when you do a search, it makes an ajax call for each keypress. Is there a way for it to wait until the user is finished typing?
This discussion has been closed.
Replies
Hth,
Gerardo
Thanks for the thought but are there any more ideas?
I think that it's a good idea.
Another approach would be to let the user to end all of his search and press on a "search" button that will do the actual search (fnDraw).
That would mean that in the "keypress" you will not write:
[code]
$("tfoot input").keyup( function () {
/* Filter on the column (the index) of this element */
oTable.fnFilter( this.value, $("tfoot input").index(this) );
} );
[/code]
but
[code]
$("tfoot input").keyup( function () {
var oSettings = oTable.fnSettings();
var iCol = $("tfoot input").index(this)
oSettings.aoPreSearchCols[ iCol ].sSearch = this.value;
} );
[/code]
If you want an exact match you can just replace the
[code]
oSettings.aoPreSearchCols[ iCol ].sSearch = this.value;
[/code]
in
[code]
oSettings.aoPreSearchCols[ iCol ].sSearch = "^\\s*"+'1'+"\\s*$";
oSettings.aoPreSearchCols[ iCol ].bRegex = false;
oSettings.aoPreSearchCols[ iCol ].bSmart= false;
[/code]
On the click of the search button just redraw the table.
Have fun!
[code]
jqFilter.keyup( function(e) {
/* Update all other filter input elements for the new display */
var n = oSettings.aanFeatures.f;
for ( var i=0, iLen=n.length ; i
This doesn't work:
[code]
{
"sExtends": "text",
"sButtonText": "Clear Search",
"fnClick": function ( nButton, oConfig, oFlash ) {
oUserTable.fnFeatureHtmlFilter (oUserTable._aoSettings);
oUserTable.fnDraw();
}
}
[/code]
What am I doing wrong? The input is not cleared as well.
[code]
{
"sExtends": "text",
"sButtonText": "Clear Search",
"fnClick": function ( nButton, oConfig, oFlash ) {
oUserTable.fnFilter('');
oUserTable.fnDraw();
}
}
[/code]
If I am reading this correctly, there is an API that was developed just for this and I use it a lot.
http://datatables.net/plug-ins/api
The function you are looking for is fnSetFilteringDelay()
I use this a lot. Play with the ms as in fnSetFilteringDelay(500), fnSetFilteringDelay(250), etc. to find the right time limits.
It will wait that amount of time before invoking the ajax call.
If I am way off base on the original problem, I apologize.
Scott
Going to try to remember to check out the API functions more carefully in the future. :D
Greg
So... I would just go for the first solution of
"instead of binding the search function to keydown, bind it to focusout?"
except I would want to bind it to the enter or return keydown, that is how flexigrid worked.
But how should I do this? We aren't suggesting to modify the source are we? This is something I loathe.
Thanks in advance!
Jon
although the delay thing might be cool... still would like to know how to change binding of things if it is possible without changing the source.
Allan
The api looks great, basically I can do anything I want....
Next I need to allow specification of the columns to be searched instead of just all of them all the time, but it won't be hard with the api. I read earlier today where I can push some custom info into the outgoing request, just have to look that up again...
I wasn't sure what the purpose of the line
$.fn.dataTableExt.iApiIndex = i;
was but it looked important so I did it also.
What is the etiquette here, should we all post on our api's that we make or is it just kind of understood that they are out there and we don't all have to share them all?
[code]
jQuery.fn.dataTableExt.oApi.fnSetFilteringPressEnter = function (oSettings) {
/*
* Type: Plugin for DataTables (www.datatables.net) JQuery plugin.
* Name: dataTableExt.oApi.fnSetFilteringPressEnter
* Version: 2.2.1
* Description: Enables filtration to be triggered by pressing the enter key instead of keyup or delay.
* Inputs: object:oSettings - dataTables settings object
*
* Returns: JQuery
* Usage: $('#example').dataTable().fnSetFilteringPressEnter();
* Requires: DataTables 1.6.0+
*
* Author: Jon Ranes (www.mvccms.com)
* Created: 4/17/2011
* Language: Javascript
* License: GPL v2 or BSD 3 point style
* Contact: jranes /AT\ mvccms.com
*/
var _that = this;
this.each(function (i) {
$.fn.dataTableExt.iApiIndex = i;
var $this = this;
var anControl = $('input', _that.fnSettings().aanFeatures.f);
anControl.unbind('keyup').bind('keypress', function (e) {
if (e.which == 13) {
$.fn.dataTableExt.iApiIndex = i;
_that.fnFilter(anControl.val());
}
});
return this;
});
return this;
}
/* Example call */
$(document).ready(function() {
$('.dataTable').dataTable().fnSetFilteringPressEnter();
} );
[/code]
That's superb - thanks for sharing your code with us :-). I've put it up on the plug-ins page here: http://datatables.net/plug-ins/api#fnFilterOnReturn . I've modified the header a little bit to make it easier to see all the code (done the same to the filtering delay function as well now - it was a bit verbose... if you'd like anything changed / added, just let me know). I've also named the function fnFilterOnReturn which I think might be slightly more appropriate for the action - although it's easy for any one to change. Hope this is okay :-)
Regards,
Allan
I also just finished up one more thing that .NET people might find to be epically awesome, and I mean epically. Basically I figured out how to use Dynamic Linq with a Generic IQueryable to build predicates for searching all columns of the grid with the much sought after "or" effect needed when building predicates. What that means is one reusable code piece can now search all the columns of any grid here.
I have a write up on it here http://www.ranessoftwareconsulting.com/articles/reusable-dynamiclinq-with-predicatebuilder-to-search-every-column-of-jquerydatatables.
And the full source of it is in the MvcCms project at codeplex in the source code section, this won't make it to release till later this year.
Basically what you end up with is a filter method like this...
[code]
using System;
using System.Linq;
using MvcCms.Data.DynamicLINQ;
using MvcCms.Service.Models;
using System.Linq.Expressions;
namespace MvcCms.Service.Code
{
public static class DataTablesSearch
{
//
//This implemenation of DataTables filter will be for small return sets.
//Will have another implementation for small sets that loads
//from the dom also. Both of these will have all fields searchable by default.
//Will have another using sprocs for all the searching for large tables.
//
public static IQueryable SearchForDataTables(this IQueryable query, DataTablesRequest dataTablesRequest, string[] columnNames)
{
if (!String.IsNullOrEmpty(dataTablesRequest.sSearch))
{
#region Search All Fields
var predicate = PredicateBuilder.False();
if (dataTablesRequest.sSingleSearchField == "All")
{
Expression predicateToAdd = null;
for (int i = 0; i < dataTablesRequest.iColumns; i++)
{
if (dataTablesRequest.bSearchable[i]) // If the column is marked as searchable
{
string columnName = columnNames[i];
Type columnType = query.DynamicType(z => z[columnName]);
if (columnType == typeof(System.Int32))
{
var intToSearchFor = int.Parse(dataTablesRequest.sSearch);
//for integer we do equals
predicateToAdd = query.DynamicWhereForPredicateBuilder(z => z[columnName] == intToSearchFor);
}
else if (columnType == typeof(System.String))
{ //for string we do contains
predicateToAdd = query.DynamicWhereForPredicateBuilder(z => z[columnName].Contains(dataTablesRequest.sSearch)); //contains or
}
predicate = predicate.Or(predicateToAdd);
}
}
query = query.Where(predicate);
}
#endregion
#region Search Single Field
else if (!String.IsNullOrEmpty(dataTablesRequest.sSingleSearchField))
{
string columnName = dataTablesRequest.sSingleSearchField;
Type columnType = query.DynamicType(z => z[columnName]);
if (columnType == typeof(System.Int32))
{
try
{
var intToSearchFor = int.Parse(dataTablesRequest.sSearch);
//for integer we do equals
query = query.DynamicWhere(z => z[columnName] == intToSearchFor);
}
catch { }
}
else if (columnType == typeof(System.String))
{
//for string we do contains
query = query.DynamicWhere(z => z[columnName].Contains(dataTablesRequest.sSearch));
}
}
#endregion
}
return query;
}
}
}
[/code]