Introduction
Generally, we use the browser back button frequently to go to the back/previous pages. It is most useful when we are searching using search controls (textboxes, dropdowns, buttons..), or when using paging, sorting etc.
In all these cases, when there is a postback, the browser is updated with the information of the page visited, and hence the back button gets enabled automatically. However, if we are updating pages using AJAX asynchronous requests, updating the browser history is not taken care automatically. We need to do some tweaks to achieve this, and enable the browser back button by storing the state into the browser history.
The original article was posted at: http://interviews.dotnetthread.com/2009/02/enabling-browser-back-button-for.html.
Description
In a normal web page developed using ASP.NET, browser history is updated for every postback, i.e., when the user clicks on the paging links, sorting links, or search buttons etc. Hence, the user can easily check the previous records by clicking on the browser back button.
In an AJAX enabled web page, where we have a GridView
inside an UpdatePanel
, browser history does not get updated as post back happens asynchronously, which the browser is not aware of.
In ASP.NET AJAX 3.5
In .NET Framework 3.5, we have AJAX extensions like ScriptManager
and UpdatePanel
, using which we develop AJAX enabled web pages.
In ASP.NET SP1, we have a History
control which allows us to add history points to our AJAX enabled page’s postbacks and hence enable the back button navigation for users.
Enabling the browser back button for GridView paging and sorting using History points in ASP.NET 3.5 SP1
- Set the property
EnableHistory="true"
for the ScriptManager
. - GridView paging:
- Handle the
OnPageIndexChanging
event of the GridView
with an event handler (e.g.: OnPageIndexChanging = "GridView1_PageIndexChanging"
). - Add the following handler code in the code-behind:
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
if (ScriptManager1.IsInAsyncPostBack && !ScriptManager1.IsNavigating)
{
ScriptManager1.AddHistoryPoint("PageIndex",
GridView1.PageIndex.ToString());
}
}
- Handle the
OnNavigate
event of the ScriptManager
with an event handler (e.g.: OnNavigate="ScriptManager1_Navigate"
). - Add the following handler code in the code-behind:
protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
string pageIndex = e.State["PageIndex"];
if (string.IsNullOrEmpty(pageIndex))
{
GridView1.PageIndex = 0;
}
else
{
GridView1.PageIndex = Convert.ToInt32(pageIndex);
}
}
- Now, we can navigate across the pages with an enabled back button.
- In the above case,
PageIndex
is stored in the URL in encrypted format (the page state is encoded in the querystring of the browser, meaning that visitors can bookmark a particular state of an AJAX application). If you make EnableSecureHistoryState=“false”
, then it is directly visible in the URL as: http://localhost/Sample/Default.aspx#&&PageIndex=1.
- GridView sorting:
- Handle the
OnSorting
event of the GridView
with an event handler (e.g.: OnSorting="GridView1_Sorting"
). - Add the following handler code in the code-behind:
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
ScriptManager1.AddHistoryPoint("SortExpression", e.SortExpression);
ScriptManager1.AddHistoryPoint("SortDirection",
e.SortDirection.ToString());
}
- Handle the
OnNavigate
event of the ScriptManager
with an event handler (e.g.: OnNavigate="ScriptManager1_Navigate"
). - Add the following handler code in the code-behind:
protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
if (!string.IsNullOrEmpty(e.State["SortExpression"]))
{
string sortExpression = e.State["SortExpression"];
SortDirection sortDirection =
(SortDirection)Enum.Parse(typeof(SortDirection),
e.State["SortDirection"]);
GridView1.Sort(sortExpression, sortDirection);
}
}
- In the above case,
SortExpression
and SortDirection
are stored in the URL in encrypted format (the page state is encoded in the querystring of the browser, meaning that visitors can bookmark a particular state of an AJAX application). If you make EnableSecureHistoryState = “false”
, then it is directly visible in the URL as http://localhost/Sample/Default.aspx#&&SortDirection= Ascending&SortExpression=SectorName.
Enabling browser back button for GridView paging and sorting in ASP.NET 2.0 (AJAX 1.1) using Nikhil's UpdateControls
- Download Nikhil's UpdateControls here: http://www.nikhilk.net/Content/Samples/UpdateControls.zip.
- Create an AJAX enabled website in ASP.NET 2.0.
- Add a reference to UpdateControls.dll.
- Register the tagprefix:
<%@ Register Assembly="nStuff.UpdateControls"
Namespace="nStuff.UpdateControls" TagPrefix="uc" %>
Then, add the UpdateHistory
control below the ScriptManager
.
<uc:UpdateHistory ID="UpdateHistory1" runat="server"
OnNavigate="ScriptManager1_Navigate">
</uc:UpdateHistory>
- GridView paging and sorting:
- Handle the
GridView
's Sorting
and PageIndexChanging
events as below, where we will add an entry to the History with PageIndex
or SortExpression
and Direction
.
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
UpdateHistory1.AddEntry("SortDirection=" +
e.SortDirection.ToString() + "&&SortExpression=" + e.SortExpression);
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
ScriptManager1.AddHistoryPoint("SortExpression", e.SortExpression);
ScriptManager1.AddHistoryPoint("SortDirection", e.SortDirection.ToString());
}
- Finally, we need to handle the
OnNavigate
event of the UpdateHistory
control to get the PageIndex
and SortExpression
and set them to the GridView
. This OnNavigate
event is fired when the user tries to navigate using the browser back and forward buttons.
protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
{
string entryName = e.EntryName.ToString();
if (e.EntryName.Contains("SortDirection") &&
e.EntryName.Contains("SortExpression"))
{
string[] splitter = new String[1];
splitter[0] = "&&";
string[] text = e.EntryName.Split(splitter, StringSplitOptions.None);
string sortExpression = text[1].Replace("SortExpression=", "");
string strSortDirection = text[0].Replace("SortDirection=", "");
SortDirection sortDirection =
(SortDirection)Enum.Parse(typeof(SortDirection), strSortDirection);
GridView1.Sort(sortExpression, sortDirection);
}
string pageIndex = string.Empty;
if (e.EntryName.Contains("PageIndex"))
{
pageIndex = e.EntryName.Replace("PageIndex=", "");
}
if (string.IsNullOrEmpty(pageIndex))
{
GridView1.PageIndex = 0;
}
else
{
GridView1.PageIndex = Convert.ToInt32(pageIndex);
}
}
We can achieve the same functionality using the following libraries as well:
- SWFAddress
- History Event: jQuery Plug-in
- RSH (Really Simple History): http://plugins.jquery.com/project/historyevent. For example: http://www.justise.com/2009/01/26/enabling-the-back-button-in-ajax-applications/.
- HistoryManager: Mootools Plug-in
Original article posted at: http://interviews.dotnetthread.com/2009/02/enabling-browser-back-button-for.html.
Happy coding with AJAX…..