I've been working through examples in several books and blogs and one of the coolest examples I've come across involves searching and sorting by drilling down through a specified column. After you've clicked on a column header to sort the data in a Gridview, you can then enter a search string into the textbox and restrict the search results even further all without refreshing the page.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="filter.aspx.cs" Inherits="Filter" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<style type="text/css">
.highlight {
background-color: yellow;
}
</style>
<title>Movie Gridview Filter</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="conditional">
<ContentTemplate>
<div>
Filter Selected Column (<asp:Label ID="lblSelectedColumn" runat="server" />):
<asp:TextBox ID="FilterText" runat="server" OnTextChanged="FilterText_TextChanged" />
</div>
<p>
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" AllowPaging="True"
AutoGenerateColumns="False" AllowSorting="True" EmptyDataText="There are no records to display"
Cellpadding="3" GridLines="Vertical" OnRowDataBound="GridView1_RowDataBound"
OnPageIndexChanged="GridView1_PageIndexChanged" OnSorted="GridView1_Sorted" BackColor="White"
BorderColor="#999999" BorderStyle="None" BorderWidth="1px" Font-Names="Verdana,sans-serif" Font-Size="X-Small"
HorizontalAlign="Center" Width="90%">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
<asp:BoundField DataField="Director" HeaderText="Director" SortExpression="Director" />
<asp:BoundField DataField="DateReleased" HeaderText="DateReleased" DataFormatString="{0:dd-MMM-yy}"
SortExpression="DateReleased" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="#DCDCDC" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ConnectionStrings:MyDatabase %>"
SelectCommand="SELECT Title, Director, DateReleased, Description FROM Movies"></asp:SqlDataSource>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="FilterText" EventName="TextChanged" />
</Triggers>
</asp:UpdatePanel>
</p>
</div>
</form>
<script type="text/javascript">
Sys.Application.add_load(page_load);
Sys.Application.add_unload(page_unload);
function page_load() {
$addHandler($get('FilterText'), 'keydown', onFilterTextChanged);
}
function page_unload() {
$removeHandler($get('FilterText'), 'keydown', onFilterTextChanged);
}
var timeoutID = 0;
function onFilterTextChanged(e) {
if (timeoutID) {
window.clearTimeout(timeoutID);
}
timeoutID = window.setTimeout(updateFilterText, 1000);
}
function updateFilterText() {
__doPostBack('FilterText', '');
}
</script>
</body>
</html>filter.aspx.cs:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class Filter : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
GridView1.Sort("Title", SortDirection.Ascending);
lblSelectedColumn.Text = "Title";
}
protected void GridView1_Sorted(object sender, EventArgs e)
{
UpdateFilter();
}
protected void GridView1_PageIndexChanged(object sender, EventArgs e)
{
UpdateFilter();
}
protected void Filter_Click(object sender, EventArgs e)
{
UpdateFilter();
}
protected void FilterText_TextChanged(object sender, EventArgs e)
{
UpdateFilter();
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow)
return;
if (String.IsNullOrEmpty(SqlDataSource1.FilterExpression))
return;
int colIndex = GetColumnIndex(GridView1.SortExpression);
TableCell cell = e.Row.Cells[colIndex];
string cellText = cell.Text;
int leftIndex = cellText.IndexOf(FilterText.Text, StringComparison.OrdinalIgnoreCase);
int rightIndex = leftIndex + FilterText.Text.Length;
StringBuilder builder = new StringBuilder();
builder.Append(cellText, 0, leftIndex);
builder.Append("<span class=\"highlight\">");
builder.Append(cellText, leftIndex, rightIndex - leftIndex);
builder.Append("</span>");
builder.Append(cellText, rightIndex, cellText.Length - rightIndex);
cell.Text = builder.ToString();
}
private void UpdateFilter()
{
string filterExpression = null;
if (!String.IsNullOrEmpty(FilterText.Text))
filterExpression = string.Format("[{0}] LIKE '%{1}%'", GridView1.SortExpression, FilterText.Text);
lblSelectedColumn.Text = GridView1.SortExpression;
SqlDataSource1.FilterExpression = filterExpression;
}
private int GetColumnIndex(string columnName)
{
for (int i = 0; i < GridView1.Columns.Count; i++)
{
BoundField field = GridView1.Columns[i] as BoundField;
if (field != null && field.DataField == columnName)
return i;
}
return -1;
}
}