Recipe 1.18 Displaying a Pop-Up Details Window

     

1.18.1 Problem

You want to provide additional details for each row in a DataGrid using a pop-up window.

1.18.2 Solution

Add a Details button to each row in the Datagrid . When the user clicks the button, open a new browser window, obtain the information from the server, and then display the detailed information in a pop-up window. An example of the output that is possible with this approach is shown in Figure 1-22 (sample DataGrid ) and Figure 1-23 (sample pop-up window output). As with the other recipes in this book, we've implemented a complete application that illustrates this approach. The form and code-behind for the page containing the sample DataGrid is shown in Example 1-51 through Example 1-53, and the form and code-behind for the sample pop-up window is shown in Example 1-54 through Example 1-56.

Figure 1-22. DataGrid with pop-up details window output
figs/ancb_0122.gif

Figure 1-23. Pop-up details window output
figs/ancb_0123.gif

1.18.3 Discussion

To implement this solution, create a DataGrid in the normal fashion, but add a link button column to display a Details link. The idea is that when the user clicks the Details link within a row of the DataGrid , the browser opens a new window and requests the appropriate page from the server. In the context of our example that implements this solution, a book details page is requested . From here on, the recipe's remaining steps are described in the context of our example because we use techniques that you are likely to find helpful in implementing your own application.

In our example, when the book details page is processed , a book ID is extracted from the query string and is then used in the database query to get the detailed data for the specific book, as shown in the setupForm method of Example 1-55 (VB) and Example 1-56 (C#).

When building a Details link in the .aspx file, an HTML anchor tag is placed in the ItemTemplate for the column. (The purpose of the anchor tag is to request the details page when the associated link button is clicked.) The target property of the HTML anchor is set to " _blank ", causing a new browser window to open when the link is clicked.

The Page_Load method in the code-behind is nearly identical to that used in other recipes, with only one small change. The line of code shown next is added to populate the DataKeys collection of the DataGrid with the primary key values for the rows being displayed. This causes the DataGrid to keep track of the primary key value for each row without our having to output the data in a hidden column. These values are needed later to display the book details.

 
figs/vbicon.gif
 dgBooks.DataKeyField = "BookID" 
figs/csharpicon.gif
 dgBooks.DataKeyField = "BookID"; 

The DataGrid control's ItemDataBound event is used to set the href value for the "details" HTML anchors added to the DataGrid . Because this event is called independently for every row in the DataGrid , the item type must be checked to see if this event applies for a given data row.

When the event does apply to a data row, the first thing we must do is get the ID of the book being displayed in the row, as shown here:

 
figs/vbicon.gif
 bookID = CInt(dgBooks.DataKeys(e.Item.ItemIndex)) 
figs/csharpicon.gif
 bookID = (int)(dgBooks.DataKeys[e.Item.ItemIndex]); 

Next, we need to get a reference to the "details" HTML anchor in the row. Because ItemTemplates were used and the anchor controls in the templates were given IDs, we can accomplish this by using the FindControl method of the passed item. If a standard BoundColumn were used instead, the data would have to be accessed using the cells collection (e.g., e.Item.Cells(1).controls(1) would access the anchor control in this example). Providing an ID and using FindControl eliminates the potential for broken code if the columns are later reordered. Note that the control must be cast to an HTMLAnchor because the controls collection is a collection of objects.

After obtaining a reference to the HTML anchor tag, we need to set the href property of the anchor to the name of the details page. In addition, the URL needs to include " BookID = n " where n is the ID of the book displayed in the row. The resulting anchor tag in the DataGrid for BookID = 1 is shown here:

 <a href="/ASPNetCookbook/VBExamples/BookDetails.aspx?BookID=1" id="dgBooks_ _ctl3_lnkDetails" target="_blank"> 

The ID is altered by ASP.NET to ensure all server controls have unique IDs. ASP.NET maintains both the original ID and the unique ID, so the original ID we provided with the FindControl method is handled correctly, sparing us from having to figure out the unique ID or dealing with indexing into items and cells.


Example 1-51. DataGrid with pop-up details window (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH01DatagridWithPopupDetailsVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH01DatagridWithPopupDetailsVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>DataGrid With Popup Details</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmDatagrid" method="post" runat ="server"> <table width="100%" cellpadding ="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> DataGrid With Popup Details (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center">  <asp:DataGrid   id="dgBooks"   runat="server"   BorderColor="000080"   BorderWidth="2px"   AutoGenerateColumns="False"   width="100%">   <HeaderStyle   HorizontalAlign="Center"   ForeColor="#FFFFFF"   BackColor="#000080"   Font-Bold=true   CssClass="TableHeader" />   <ItemStyle   BackColor="#FFFFE0"   cssClass="TableCellNormal" />   <AlternatingItemStyle   BackColor="#FFFFFF"   cssClass="TableCellAlternating" />     <Columns>   <asp:BoundColumn HeaderText="Title" DataField="Title" />   <asp:TemplateColumn ItemStyle-HorizontalAlign="Center">   <ItemTemplate>   <a id="lnkDetails" runat="server"   target="_blank">Details</a>   </ItemTemplate>   </asp:TemplateColumn>   </Columns>   </asp:DataGrid>  </td> </tr> </table> </form> </body> </html> 

Example 1-52. DataGrid with pop-up details window code-behind (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH01DatagridWithPopupDetailsVB.aspx.vb ' ' Description: This class provides the code behind for ' CH01DatagridWithPopupDetailsVB ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Configuration Imports System.Data Imports System.Data.OleDb Imports System.Web.UI.HtmlControls Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples Public Class CH01DatagridWithPopupDetailsVB Inherits System.Web.UI.Page 'controls on form Protected WithEvents dgBooks As System.Web.UI.WebControls.DataGrid '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Dim dbConn As OleDbConnection Dim da As OleDbDataAdapter Dim ds As DataSet Dim strConnection As String Dim strSQL As String If (Not Page.IsPostBack) Then Try 'get the connection string from web.config and open a connection 'to the database strConnection = _ ConfigurationSettings.AppSettings("dbConnectionString") dbConn = New OleDb.OleDbConnection(strConnection) dbConn.Open( ) 'build the query string and get the data from the database strSQL = "SELECT BookID, Title " & _ "FROM Book " & _ "ORDER BY Title" da = New OleDbDataAdapter(strSQL, dbConn) ds = New DataSet da.Fill(ds) 'set the source of the data for the datagrid control and bind it  dgBooks.DataKeyField = "BookID"  dgBooks.DataSource = ds dgBooks.DataBind( ) Finally 'cleanup If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If End Try End If End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: dgBooks_ItemDataBound ' ' DESCRIPTION: This routine is the event handler that is called for each ' item in the datagrid after a data bind occurs. It is ' responsible for setting the URL of the anchor tags to the ' page used to display the details for a book '-------------------------------------------------------------------------  Private Sub dgBooks_ItemDataBound(ByVal sender As Object, _   ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _   Handles dgBooks.ItemDataBound   Const DETAIL_PAGE As String = "CH01BookDetailsVB.aspx"   Dim bookID As Integer   Dim anchor As HtmlAnchor   'check the type of item that was databound and only take action if it   'was a row in the datagrid   If ((e.Item.ItemType = ListItemType.Pager) Or _   (e.Item.ItemType = ListItemType.Header) Or _   (e.Item.ItemType = ListItemType.Footer)) Then   'do nothing   Else   'the item that was bound is an "Item", "AlternatingItem", "EditItem",   '"SelectedItem" or "Separator" (in other words a row)   bookID = CInt(dgBooks.DataKeys(e.Item.ItemIndex))   'get the anchor tag in the row   'NOTE: This can be done by using the FindControl method of the passed   ' item because ItemTemplates were used and the anchor controls in   ' the templates where given IDs. If a standard BoundColumn was   ' used, the data would have to be accessed using the cells   ' collection (e.g. e.Item.Cells(1).controls(1) would access the   ' anchor control in this example.   anchor = CType(e.Item.FindControl("lnkDetails"), _   HtmlAnchor)   'set the URL of the anchor tag to the page used to display the book   'details passing the ID of the book in the querystring   anchor.HRef = DETAIL_PAGE & "?BookID=" & bookID.ToString( )   End If   End Sub 'dgBooks_ItemDataBound  End Class 'CH01DatagridWithPopupDetailsVB End Namespace 

Example 1-53. DataGrid with pop-up details window code-behind (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH01DatagridWithPopupDetailsCS.aspx.cs // // Description: This class provides the code behind for // CH01DatagridWithPopupDetailsCS.aspx // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace ASPNetCookbook.CSExamples { public class CH01DatagridWithPopupDetailsCS : System.Web.UI.Page { // controls on form protected System.Web.UI.WebControls.DataGrid dgBooks; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. // //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { OleDbConnection dbConn = null; OleDbDataAdapter da = null; DataSet ds = null; String strConnection = null; String strSQL =null; // wire the item data bound event this.dgBooks.ItemDataBound += new DataGridItemEventHandler(this.dgBooks_ItemDataBound); if (!Page.IsPostBack) { try { // get the connection string from web.config and open a connection // to the database strConnection = ConfigurationSettings.AppSettings["dbConnectionString"]; dbConn = new OleDbConnection(strConnection); dbConn.Open( ); // build the query string and get the data from the database strSQL = "SELECT BookID, Title " + "FROM Book " + "ORDER BY Title"; da = new OleDbDataAdapter(strSQL, dbConn); ds = new DataSet( ); da.Fill(ds); // set the source of the data for the datagrid control and bind it  dgBooks.DataKeyField = "BookID";  dgBooks.DataSource = ds; dgBooks.DataBind( ); } // try finally { // clean up if (dbConn != null) { dbConn.Close( ); } } // finally } } // Page_Load //************************************************************************ // // ROUTINE: dgBooks_ItemDataBound // // DESCRIPTION: This routine is the event handler that is called for each // item in the datagrid after a data bind occurs. It is // responsible for setting the URL of the anchor tags to the // page used to display the details for a book // //------------------------------------------------------------------------  private void dgBooks_ItemDataBound(Object sender,   System.Web.UI.WebControls.DataGridItemEventArgs e)   {   const String DETAIL_PAGE = "CH01BookDetailsCS.aspx";   int bookID;   HtmlAnchor anchor = null;   // check the type of item that was databound and only take action if it   // was a row in the datagrid   if ((e.Item.ItemType == ListItemType.Pager)   (e.Item.ItemType == ListItemType.Header)   (e.Item.ItemType == ListItemType.Footer))   {   // do nothing   }   else   {   // the item that was bound is an "Item", "AlternatingItem",   // "EditItem", "SelectedItem" or "Separator" (in other words a row)   bookID = (int)(dgBooks.DataKeys[e.Item.ItemIndex]);   // get the anchor tag in the row   // NOTE: This can be done by using the FindControl method of the   // passeditem because ItemTemplates were used and the anchor   // controls in the templates where given IDs. If a standard   // BoundColumn was used, the data would have to be accessed   // using the cells collection (e.g. e.Item.Cells(1).controls(1)   // would access the anchor control in this example.   anchor = (HtmlAnchor)(e.Item.FindControl("lnkDetails"));   // set the URL of the anchor tag to the page used to display the book   // details passing the ID of the book in the querystring   anchor.HRef = DETAIL_PAGE + "?BookID=" + bookID.ToString( );   }   } // dgBooks_ItemDataBound  } // CH01DatagridWithPopupDetailsCS } 

Example 1-54. Pop-up detail page (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH01BookDetailsVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH01BookDetailsVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Book Details</title> <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0"> <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> <meta name=vs_defaultClientScript content="JavaScript"> <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5"> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmDatagrid" method="post" runat="server"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Book Details (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <!-- Put book details here --> <table width="600" border="0"> <tr> <td rowspan="6" align="center" width="250"> <img id="imgBook" runat="server"></td> <td class="TableCellNormal" width="150">Title: </td> <td id="bookTitle" runat="server" class="TableCellNormal" width="325"></td> </tr> <tr> <td class="TableCellNormal">ISBN: </td> <td id="isbn" runat="server" class="TableCellNormal"></td> </tr> <tr> <td class="TableCellNormal">Publisher: </td> <td id="publisher" runat="server" class="TableCellNormal"></td> </tr> <tr> <td class="TableCellNormal">Publish Date: </td> <td id="publishDate" runat="server" class="TableCellNormal"></td> </tr> <tr> <td class="TableCellNormal">List Price: </td> <td id="listPrice" runat="server" class="TableCellNormal"></td> </tr> <tr> <td class="TableCellNormal">Discounted Price: </td> <td id="discountedPrice" runat="server" class="TableCellNormal"></td> </tr> </table> </td> </tr> </table> </form> </body> </html> 

Example 1-55. Pop-up detail page code-behind (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH01BookDetailsVB.aspx.vb ' ' Description: This class provides the code behind for ' CH01BookDetailsVB.aspx ' '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Configuration Imports System.Data Imports System.Data.OleDb Namespace ASPNetCookbook.VBExamples Public Class CH01BookDetailsVB Inherits System.Web.UI.Page 'controls on form Protected imgBook As System.Web.UI.HtmlControls.HtmlImage Protected bookTitle As System.Web.UI.HtmlControls.HtmlTableCell Protected isbn As System.Web.UI.HtmlControls.HtmlTableCell Protected publisher As System.Web.UI.HtmlControls.HtmlTableCell Protected publishDate As System.Web.UI.HtmlControls.HtmlTableCell Protected listPrice As System.Web.UI.HtmlControls.HtmlTableCell Protected discountedPrice As System.Web.UI.HtmlControls.HtmlTableCell '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Dim dbConn As OleDbConnection Dim dCmd As OleDbCommand Dim dReader As OleDbDataReader Dim strConnection As String Dim strSQL As String Dim bookID As String If (Not Page.IsPostBack) Then Try  'get the book ID from the querystring in the URL   If (IsNothing(Request.QueryString.Item("BookID"))) Then   'production code needs to handle the page request without the needed   'information in the querystring here   Else   bookID = Request.QueryString.Item("BookID").ToString( )   'get the connection string from web.config and open a connection   'to the database   strConnection = _   ConfigurationSettings.AppSettings("dbConnectionString")   dbConn = New OleDbConnection(strConnection)   dbConn.Open( )   'build the query string and get the data from the database   strSQL = "SELECT Title, ISBN, Publisher, PublishDate, " & _   "ListPrice, DiscountedPrice, ImageFilename " & _   "FROM Book " & _   "WHERE BookID=?"   dCmd = New OleDbCommand(strSQL, dbConn)   dCmd.Parameters.Add(New OleDbParameter("BookID", bookID))   dReader = dCmd.ExecuteReader( )   If (dReader.Read) Then   'set the data in the individual controls on the page   imgBook.Src = "images/books/" & _   dReader.Item("ImageFilename").ToString( )   bookTitle.InnerText = dReader.Item("Title").ToString( )   isbn.InnerText = dReader.Item("ISBN").ToString( )   publisher.InnerText = dReader.Item("Publisher").ToString( )   publishDate.InnerText = Format(dReader.Item("PublishDate"), _   "MMM dd, yyyy")   listPrice.InnerText = Format(dReader.Item("ListPrice"), _   "C2")   discountedPrice.InnerText = Format(dReader.Item("DiscountedPrice"), _   "C2")   End If  End If Finally 'cleanup If (Not IsNothing(dReader)) Then dReader.Close( ) End If If (Not IsNothing(dbConn)) Then dbConn.Close( ) End If End Try End If End Sub 'Page_Load End Class 'CH01BookDetailsVB End Namespace 

Example 1-56. Pop-up detail page code-behind (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH01BookDetailsCS.aspx.cs // // Description: This class provides the code behind for // CH01BookDetailsCS.aspx // //**************************************************************************** using System; using System.Configuration; using System.Data; using System.Data.OleDb; namespace ASPNetCookbook.CSExamples { public class CH01BookDetailsCS : System.Web.UI.Page { // controls on form protected System.Web.UI.HtmlControls.HtmlImage imgBook; protected System.Web.UI.HtmlControls.HtmlTableCell bookTitle ; protected System.Web.UI.HtmlControls.HtmlTableCell isbn; protected System.Web.UI.HtmlControls.HtmlTableCell publisher; protected System.Web.UI.HtmlControls.HtmlTableCell publishDate; protected System.Web.UI.HtmlControls.HtmlTableCell listPrice; protected System.Web.UI.HtmlControls.HtmlTableCell discountedPrice; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. // //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) { OleDbConnection dbConn = null; OleDbCommand dCmd = null; OleDbDataReader dReader = null; String strConnection = null; String strSQL = null; String bookID = null; DateTime pubDate; Decimal price; if (!Page.IsPostBack) { try {  // get the book ID from the querystring in the URL   if (Request.QueryString["BookID"] == null)   {   // production code needs to handle the page request without the   // needed information in the querystring here   }   else   {   bookID = Request.QueryString["BookID"].ToString( );   // get the connection string from web.config and open a connection   // to the database   strConnection =   ConfigurationSettings.AppSettings["dbConnectionString"];   dbConn = new OleDbConnection(strConnection);   dbConn.Open( );   // build the query string and get the data from the database   strSQL = "SELECT Title, ISBN, Publisher, PublishDate, " +   "ListPrice, DiscountedPrice, ImageFilename " +   "FROM Book " +   "WHERE BookID=?";   dCmd = new OleDbCommand(strSQL, dbConn);   dCmd.Parameters.Add(new OleDbParameter("BookID", bookID));   dReader = dCmd.ExecuteReader( );   if (dReader.Read( ))   {   // set the data in the individual controls on the page   imgBook.Src = "images/books/" +   dReader["ImageFilename"].ToString( );   bookTitle.InnerText = dReader["Title"].ToString( );   isbn.InnerText = dReader["ISBN"].ToString( );   publisher.InnerText = dReader["Publisher"].ToString( );   pubDate = (DateTime)dReader["PublishDate"];   publishDate.InnerText = pubDate.ToString("MMM dd, yyyy");   price = (Decimal)dReader["ListPrice"];   listPrice.InnerText = price.ToString("C2");   price = (Decimal)dReader["DiscountedPrice"];   discountedPrice.InnerText = price.ToString("C2");   }   }  } // try finally { // clean up if (dReader != null) { dReader.Close( ); } if (dbConn != null) { dbConn.Close( ); } } // finally } } // Page_Load } // CH01BookDetailsCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 179

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net