Search content within the blog

Tuesday, November 18, 2008

Enabling the Browser Back Button for GridView, ASP.NET AJAX History

One of the common navigation tools in a website is the back button of the browser. People use the back button quite frequently to go back to the page already visited. When there is a postback, the browser is updated with the information of the page visited and hence the back button gets enabled automatically. Assuming there is a GridView control that we are using in a page which fetches a lot of records, one of the common practices is to enable paging for the GridView such that the initial set of records loads quicker and people can page through the next set of records on a requirement basis.

When this GridView is in a normal ASP.NET Page, when users click on the paging buttons or links, the browser history gets updated and hence, if the users want to check the previous set of records, they can click on the back button and do the same.

However, in case of an ASP.NET AJAX enabled page, typically the GridView inside an Update Panel, it becomes impossible since the postback happens asynchronously and the browser history isn’t aware of the postback and hence the back button isn’t enabled.

To overcome this, ASP.NET 3.5 SP1 provides the History control that allows you to add history points to your AJAX Enabled page’s post backs and hence enable back button navigation for the users.

Let us examine this with a sample on Grid View. First, let us add a regular GridView control to an ASP.NET Page and configure it to use the NorthWind Database’s “Alphabetical list of products” table.

<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" CellPadding="4"
DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None">
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock"
SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder"
SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
</Columns>
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:GridView>

<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductName], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [CategoryName] FROM [Alphabetical list of products]">
</asp:SqlDataSource>

Note this sample assumes you have the Northwind Database installed and you have the connection string configured in the web.config to connect to the database. You can download the same from http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46a0-8da2-eebc53a68034&displaylang=en for SQL Server 2000, 2005 etc.,

When you run this page, you will be able to page through the records and hit back button to go to the previous set of records.

Let us add Script Manager and Update Panel to this page and then move the contents into the Content Template of the Update Panel.

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>

>> The above GridView code snippet goes here


</ContentTemplate>
</asp:UpdatePanel>

Now when you run the page and click on the paging numbers i.e. 1,2,3..you will notice that the back button isn't enabled since this has been an asynchronous postback within the update panel.

To handle this, we need to do the following things

1. Set the EnableHistory=”true” for the ScriptManager (in this case, ScriptManager1). The updated ScriptManager declaration looks like this

<asp:ScriptManager ID="ScriptManager1" runat="server" EnableHistory="true">
</asp:ScriptManager>

2. Handle the OnPageIndexChanging event of the GridView with an event ex.- OnPageIndexChanging="GridView1_PageIndexChanging" needs to go in the GridView declaration above.

3. Add the handler code in the code behind as follows:-

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e) {

if (ScriptManager1.IsInAsyncPostBack && !ScriptManager1.IsNavigating) {
ScriptManager1.AddHistoryPoint("Index", GridView1.PageIndex.ToString());
}
}

Basically we are checking if the ScriptManager is in an asynchronous postback and the ScriptManager is not currently navigating. The AddHistoryPoint is the method that helps us to define history points and we provide the PageIndex to the method using the GridView’s pageindex property.

4. Handle the Script Manager’s Navigate event in the declaration as OnNavigate="ScriptManager1_Navigate"

5. Add the Handler code in the codebehind as follows:-

string indexString = e.State["index"];
if (string.IsNullOrEmpty(indexString)) {
GridView1.PageIndex = 0;

} else {
int Index = Convert.ToInt32(indexString);
GridView1.PageIndex = Index;
}

Once we do the above, when you run the page and navigate across the pages, you could see that the back button is enabled and we can navigate using the back button.

Note that, if there are multiple GridView controls within the updatepanel, we need to handle them separately as currently, we are only handing GridView1. However, if the GridView or any other control is outside the scope of Update Panel, then back button enablement is taken care automatically.

Also, Sorting needs to be handled as well. For a sample on Sorting check http://aspnet.4guysfromrolla.com/articles/100808-1.aspx

No comments:

Post a Comment