DataGrid: iTunes-like incremental search

L

Luis Ferrao

Comming from Windows Forms development, I never had problems with this
issue before.

What i'm trying to achieve is an iTunes like incremental search. For
those who never used iTunes, it's basically a text field with a key
stroke event that filters the data grid as the users types in a string.
The more text in the field, the fewer fields desplayed.

The problem is that this is obviously a client side behaviour.

In windows forms, this is easily achieved with this kind of code:

private void SearchField_TextChanged(object sender, EventsArgs e)
{
string filterExpression = "Column1 LIKE '*'" + ((TextBox)
sender).Text + "'*' OR... (and so on for the rest of the columns)"
MainView.RowFilter = filterExpression;
}

In asp.net though, i fear the solution will not be as straightforward.
I would apreciate if someone had some input on how to achieve this
either by client-side script, third-party controls, etc...

Any kind of help really.

Best regards,

Luis Ferrao
 
E

Eliyahu Goldin

Luis,

On client side you don't have high-level properties like RowFilter, but you
can still make a loop that will go through the DHTML object representing the
grid, which is a table, and set the rows visibility properties according to
the text entered. You just need to find a right textbox event to handle.
onchange event fires only when you leave the textbox, not when you enter
another character. May be onkeypress?

Eliyahu
 
L

Luis Ferrao

Isn't it possible to incorporate this behaviour in a user control so
devs don't have to implement this solution each time they want a
datagrid to behave this way?

Luis Ferrao
 
J

Jeff @ Dart

Hello Luis,

Our new product (LiveControls for ASP.NET) is perfect for this type of
implementation. This is a suite of 20+ server controls that communicate
with the server using remote scripting (super quick communication with
web server, no browser refresh).

For your implementation, you could use a LiveTextBox and a LiveListBox.
Wire up the server-side KeyPress event of the LiveTextBox. In this
event, perform your SQL query with the value of LiveTextBox.Text. Bind
the recordset to the LiveListBox. The result, with each keystroke the
listbox contains the applicable search results...without refreshing the
page. This is cross browser too (tested in IE5+, Moz 1.3+ , Opera,
Konqueror, Galeon, etc).

Check out our tutorial app at
http://www.dart.com/livetutorial/display.aspx, or go to
http://www.dart.com/powerweb/livecontrols.asp to download a free trial.
 
L

Luis Ferrao

Ok, this is what i came up with. It's inspired on someone else's code
but modified to run faster.

If you're wondering why a "setInterval" instead of a link to a "onKeyUp"
event, it's because it's still kinda slow for big (1000+ rows) table
which makes InternetExplorer freeze during keystrokes... very anoying.

It must be placed after the datagrid declaration since it refers to it.

--> If anyone could see a way to make it faster, I would apreciate the
help. It can still be a little laggy on huge tables.

Luis Ferrao

PS: Jeff, i'll have a look but it sounds nice and encapsulated the way
you put it

*******************************************
***************** CODE ********************
*******************************************
var filter = "";
var tableId = "DataGrid";
var rowHeight = 16;
var table = document.getElementById(tableId);
var rows = table.getElementsByTagName('tr');
// the following must be called at the end of declarations
var listnerInterval = setInterval("applyFilter(filter)", 1000);

function applyFilter(pattern)
{
counter = 0 // visible rows counter

// iterate through and search the array (<tr>'s)
outer_loop:
for (i=0; i < rows.length; i++)
{
if (pattern == "")
{
rows.className='visible'
counter++;
continue outer_loop
}
td = rows.getElementsByTagName('td')

// iterate through <td>'s
for (j = 0; j < td.length; j++)
{
nodeVal = td[j].firstChild.nodeValue; // gets us the #text value
of the first td tag
try {
if (nodeVal.toLowerCase().indexOf(pattern.toLowerCase()) != -1
|| pattern == '')
{
// match found for this row (or pattern is ''), so set as
visible
// rows.setAttribute('class', 'visible');
rows.className='visible'
// increment visible rows counter but only once per row
if (j == 0) counter++
continue outer_loop
}
else {
// match not found for this row, so set as hidden
//rows.setAttribute('class', 'hidden');
rows.className='hidden'
}
} catch (ex) {}
}
}
// fix table height at the end of the loop
table.style.height = (counter * rowHeight) + "px"
}
*******************************************
***************** EOC *********************
*******************************************

Note: The search field onkeyup event must modify the filter var
obviously. But at least this way the app doesn't have to go through the
whole function between each keystroke.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top