Saturday, December 6, 2008

ASP.NET Search records in GridView footer and highlight results using Ajax



In this example i am populating gridview without using sqlDataSource but by creating Sqlconnection and SqlCommand.

I've put a textbox for text to search in footer of gridview using footer template , and the search results are highlighted using regular expression, i m using AJAX for partial postback and update progress template to show search progress

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Search and highlight Results in Grdiview
</title>
<style type="text/css">
.highlight {text-decoration:none; font-weight:bold;
color:black; background:yellow;}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1"
runat="server" />
<asp:UpdatePanel ID="UpdatePanel1"
runat="server">
<ContentTemplate>
<div>
<asp:GridView ID="grdSearch" runat="server"
BackColor="white" BorderColor="Aqua"
AutoGenerateColumns="false" ShowFooter="true"
OnRowCommand="grdSearch_RowCommand">
<FooterStyle BackColor="AliceBlue"
ForeColor="AntiqueWhite" />
<PagerStyle BackColor="#99CCCC"
ForeColor="#003399" HorizontalAlign="Left" />
<HeaderStyle BackColor="#003399"
Font-Bold="True" ForeColor="#CCCCFF" />

<Columns>
<asp:TemplateField HeaderText="FirstName">
<ItemTemplate>
<asp:Label ID="lblFIrstName" runat="server"
Text='<%# Highlight(Eval("FirstName").ToString()) %>'>
</asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtSearch" runat="server"
Width="70px"></asp:TextBox>
<asp:Button ID="btnSearch"
CommandName="Search"
runat="server" Text="Search"
Width="60px" />
</FooterTemplate>
</asp:TemplateField>
<asp:BoundField DataField="LastName"
HeaderText="LastName" />
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1"
runat="server">
<ProgressTemplate>
<br />
<img src="Images/ajax.gif"
alt="Searchig"  />
</ProgressTemplate>
</asp:UpdateProgress>
</form>
</body>
</html>

And the code behind first of all i m populating the Grid by making sqlconnection, Sqlcommand and fatching the data from database, than binding the data to grid view at Page_Load event after checking the page is not loading firs time by by checking flag of isPostBack
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using System.Data.SqlClient;

public partial class _Default : System.Web.UI.Page
{
string strConnection =
ConfigurationManager.AppSettings["ConnectionString"];
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}

}
private DataTable GetRecords()
{
SqlConnection conn = new SqlConnection(strConnection);
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select * from Employees";
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
DataSet objDs = new DataSet();
dAdapter.Fill(objDs);
return objDs.Tables[0];

}
private void BindGrid()
{
DataTable dt = GetRecords();
if (dt.Rows.Count > 0)
{
grdSearch.DataSource = dt;
grdSearch.DataBind();
}
}

Now i've written a method to search the text within results of GridView, which user enter in the TextBox to search
private void SearchText(string strSearchText)
{
DataTable dt = GetRecords();
DataView dv = new DataView(dt);
string SearchExpression = null;
if (!String.IsNullOrEmpty(strSearchText))
{
SearchExpression =
string.Format("{0} '%{1}%'",
grdSearch.SortExpression, strSearchText);

}
dv.RowFilter = "FirstName like" + SearchExpression;
grdSearch.DataSource = dv;
grdSearch.DataBind();
}

Next step is to check the command in RowCommand event of grid view,if it is what u've defined in while creating the button in footer of grid by assigning the commandname property, if yes than get the text entered by user in textbox placed in footer of gridview by using findcontrol method and pass this text to the search method written earlier by making a call to that method
protected void grdSearch_RowCommand
(object sender, GridViewCommandEventArgs e)
{
System.Threading.Thread.Sleep(2000);
if (e.CommandName == "Search")
{
TextBox txtGrid =
(TextBox)grdSearch.FooterRow.FindControl("txtSearch");
SearchText(txtGrid.Text);
}
}

Now to highlight the search text in results i m using regexp and replacing the the words found with highlighted in yellow color
public string Highlight(string InputTxt)
{
GridViewRow gvr = grdSearch.FooterRow;
if (gvr != null)
{
TextBox txtExample =
(TextBox)grdSearch.FooterRow.FindControl("txtSearch");

if (txtExample.Text != null)
{
string strSearch = txtExample.Text;
//string Search_Str = txtGrid.Text.ToString();
// Setup the regular expression 
//and add the Or operator.

Regex RegExp =
new Regex(strSearch.Replace(" ", "|").Trim(),
RegexOptions.IgnoreCase);


//Highlight keywords by calling the delegate 
//each time a keyword is found.
return
RegExp.Replace(InputTxt, new MatchEvaluator(ReplaceKeyWords));

// Set the RegExp to null.
RegExp = null;

}
else
return InputTxt;
}
else
{
return InputTxt;
}
}

public string ReplaceKeyWords(Match m)
{
return "<span class=highlight>" + m.Value + "</span>";
}


Download the sample code attached



Add to diigo
Shout it
Stumble Upon Toolbar
Submit this story to DotNetKicks Add to Mixx! Mixx it! add to del.icio.us saved by 0 users
Subscribe to Feeds

6 comments:

Mark Smith said...

That method is going to be an absolute killer for performance. Not only are you posting the whole page back every time a key is pressed, you are hitting the database to get the records every time.


amiT
amiT jaiN said...


@Mark Smith :I've altered the code ,download the new one and check it out


Mora said...

I think the returned data can be saved in a Cache or session and use the dataview to filter the rows and that will boost the performance


Shakti Singh Dulawat said...

This is very nice example mention my you, this is helpful for programming logic.
Thanks
Shakti
www.nextmvp.blogspot.com


Abhay Goyal said...

Thanks Amit, That was really informative and it really works, Thankyou very much , I love it.
Keep writing and helping us out.


amiT
amiT jaiN said...

@Abhay Goyal:

Thanks for the appreciation :) , keep visiting


.NET Resources

Further Readings

Find More Articles


Followers

Subscribe To Feeds

Subscribe by E-mail

Enter your email address:

Delivered by FeedBurner


Subscribe in your favorite reader

Follow me on Twitter

This site is best viewed with || You may get errors in proper display of this site if using Internet explorer


C#.NET Articles and tutorials,ASP.NET Articles - blog by amiT jaiN