Recipe 3.4 Simulating Multipage Forms

     

3.4.1 Problem

You want to create a form that appears, from the user 's prospective , to consist of multiple pages, while keeping all of your code in one .aspx file and the code-behind that accompanies it.

3.4.2 Solution

Create one ASP.NET page. Use panels to separate the HTML for each of the "virtual" pages you wish to display, and simulate a multipage form by enabling one panel at a time. The output of a typical three-page form is shown in Figures Figure 3-1 through Figure 3-3. Example 3-13 through Example 3-15 show the .aspx and code-behind files for an application that implements this solution.

Figure 3-1. Multipage form output (page 1)
figs/ancb_0301.gif

Figure 3-2. Multipage form output (page 2)
figs/ancb_0302.gif

Figure 3-3. Multipage form output (page 3)
figs/ancb_0303.gif

3.4.3 Discussion

In classic ASP, a series of questions or prompts, such as those on a survey or wizard, are typically implemented using multiple ASP pages with each submitting to the next in turn . ASP.NET allows you to submit a form to itself, which means that you have to rethink how to implement a survey, wizard, or traditionally multipart form. The solution we advocate involves defining multiple panels on a single form with the ASP:Panel control, and showing or hiding the panels as required. For example, the application we've written uses this technique to display a series of questions in a short survey.

Refer to Recipe 3.3 if you are determined to stick to the multiple form approach.


In our example, the .aspx file contains three panels and a Next button. The first panel contains the first question ("Do you currently use ASP.NET?") with two radio buttons for the response. The second panel contains the second question ("How long have you been using ASP.NET?") with a drop-down list for the response. The third panel contains a message thanking the user for taking the survey. A Next button is used to move from one panel to the next.

The code-behind contains a reference to each of the panels to provide you with the ability to show and then hide any particular panel as the survey progresses. For this example, an object, Survey , is used to save the current question number and the response to each question asked. The Survey object is marked as Serializable to allow the objects of this type to be stored in the viewstate . The class is defined as follows :

 
figs/vbicon.gif
 <  System.Serializable  ( )> Private Class Survey Public currentQuestion As Integer Public response1 As Boolean Public response2 As Integer End Class 
figs/csharpicon.gif
  [System.Serializable( )]  private class Survey { public int currentQuestion; public Boolean response1; public int response2; } 

A constant, VS_SURVEY_DATA , is used to define the name of the variable placed in the viewstate . This improves maintainability of the code, because the variable in the viewstate is accessed from several locations in the code.

In the Page_Load method, the Survey object is initialized and stored in the viewstate . The form is then set up to initially display the first question in the series.

When the Next button is clicked, the form is posted back to itself and the btnNext_Click method is executed. The first action performed is to rehydrate the Survey object from the viewstate . Next, the current question is checked to see what response should be stored and which panel should next be made visible:

  • If the first question was just answered , its response is stored in the Survey object, the question number is incremented, the Survey object is again stored in the viewstate , and the second question is made visible.

  • If the second question was just answered, its response is stored in the Survey object (more permanent storage would be used instead if this were a real application), and the thank-you panel is made visible.

This example could be extended in many ways. One enhancement would be to create a totally data-driven survey form. In the .aspx file, a panel would be needed for each type of response (free-form, yes/no, selection, etc.). In the code-behind, an XML document, database, or some other data store could be used and a collection of data defined that contains the questions, type of response, etc. Based on this data, the appropriate panel would be displayed for each question.

Another possible enhancement is that instead of collecting all of the responses and storing them in the viewstate until the survey is completed, the responses could be stored in a database or other data store as the survey proceeds. This would be a better approach if the survey is long or storing partial data is desirable.

3.4.4 See also

Recipe 3.3 for a multiple form approach

Example 3-13. Simulating a multipage form (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="Ch03MultiPageVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH03MultiPageVB" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>FormMultiPageVB</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmMultiPage" 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"> MultiPage Form (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center">  <asp:Panel ID="pnlQuestion1" Runat="server">   <table width="60%" border="0">   <tr>   <td class="MenuItem">Do you currently use ASP.NET?</td>   <td>   <asp:RadioButtonList ID="radQuestion1" Runat="server"   RepeatDirection="Horizontal"   CssClass="MenuItem" >   <asp:ListItem Value="1">   Yes   </asp:ListItem>   <asp:ListItem Value="0" Selected="True">   No   </asp:ListItem>   </asp:RadioButtonList>   </td>   </tr>   </table>   </asp:Panel>   <asp:Panel ID="pnlQuestion2" Runat="server">   <table width="80%" border="0">   <tr>   <td class="MenuItem">How long have you been using ASP.NET?</td>   <td class="MenuItem">   <select id="selQuestion2" runat="server">   <option value="0">-- Select One --</option>   <option value="1">0-6 Months</option>   <option value="2">7-12 Months</option>   <option value="3">13-24 Months</option>   <option value="4">24+ Months</option>   </select>   </td>   </tr>   </table>   </asp:Panel>   <asp:Panel ID="pnlThankyou" Runat="server">   <table width="60%" border="0">   <tr>   <td class="MenuItem" align="center">   Thank you for taking our survey   </td>   </tr>   </table>   </asp:Panel>  <br />  <asp:ImageButton ID="btnNext" Runat="server"   ImageUrl="images/buttons/button_nextQuestion.gif" />  </td> </tr> </table> </form> </body> </html> 

Example 3-14. Simulating a multipage form code-behind (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH03MultiPageVB.aspx.vb ' ' Description: This module provides the code behind for ' CH03MultiPageVB.aspx ' '***************************************************************************** Namespace ASPNetCookbook.VBExamples Public Class CH03MultiPageVB Inherits System.Web.UI.Page 'panels on the form Protected pnlQuestion1 As System.Web.UI.WebControls.Panel Protected pnlQuestion2 As System.Web.UI.WebControls.Panel Protected pnlThankyou As System.Web.UI.WebControls.Panel 'control for response to question 1 Protected radQuestion1 As System.Web.UI.WebControls.RadioButtonList 'control for response to question 2 Protected selQuestion2 As System.Web.UI.HtmlControls.HtmlSelect 'buttons to navigate through survey Protected WithEvents btnNext As System.Web.UI.WebControls.ImageButton  'the following class defines the container to store the survey data   <System.Serializable( )> Private Class Survey   Public currentQuestion As Integer   Public response1 As Boolean   Public response2 As Integer   End Class   'the following constant defines the variable used to store the survey   'data in the viewstate   Private VS_SURVEY_DATA As String = "SurveyData"  '************************************************************************* ' ' 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 surveyData As Survey  If (Not Page.IsPostBack) Then   'initialize survey data   surveyData = New Survey   surveyData.currentQuestion = 1   surveyData.response1 = False   surveyData.response2 = -1   'store the survey in the viewstate to use on the   'next submittal   viewstate.Add(VS_SURVEY_DATA, surveyData)   'make the first question visible   pnlQuestion1.Visible = True   pnlQuestion2.Visible = False   pnlThankyou.Visible = False   End If  End Sub 'Page_Load '************************************************************************* ' ' ROUTINE: btnNext_Click ' ' DESCRIPTION: This routine provides the event handler for the next ' button click event. '-------------------------------------------------------------------------  Private Sub btnNext_Click(ByVal sender As Object, _   ByVal e As System.Web.UI.ImageClickEventArgs) _   Handles btnNext.Click   Dim surveyData As Survey   'get the object from the viewstate with the survey data   surveyData = CType(viewstate.Item(VS_SURVEY_DATA), Survey)   Select Case surveyData.currentQuestion   Case 1   'store answer to first question   If (radQuestion1.SelectedItem.Value = "0") Then   surveyData.response1 = False   Else   surveyData.response1 = True   End If   'increment the question number   surveyData.currentQuestion += 1   'store the survey in the viewstate to use on the   'next submittal   viewstate.Add(VS_SURVEY_DATA, surveyData)   'make 2nd question visible   pnlQuestion1.Visible = False   pnlQuestion2.Visible = True   Case 2   'store answer to second question   surveyData.response2 = CInt(selQuestion2.Value)   'the survey is complete so store the answers per your   'applications required (database, etc.)   'make thank you panel visible   pnlQuestion2.Visible = False   pnlThankyou.Visible = True   btnNext.Visible = False   Case Else   'error case   End Select   End Sub 'btnNext_Click  End Class 'CH03MultiPageVB End Namespace 

Example 3-15. Simulating a multipage form code-behind (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH03MultiPageCS.aspx.cs // // Description: This module provides the code behind for // CH03MultiPageCS.aspx // //**************************************************************************** using System; using System.Web.UI; namespace ASPNetCookbook.CSExamples { public class CH03MultiPageCS : System.Web.UI.Page { // panels on the form protected System.Web.UI.WebControls.Panel pnlQuestion1; protected System.Web.UI.WebControls.Panel pnlQuestion2; protected System.Web.UI.WebControls.Panel pnlThankyou; // control for response to question 1 protected System.Web.UI.WebControls.RadioButtonList radQuestion1; // control for response to question 2 protected System.Web.UI.HtmlControls.HtmlSelect selQuestion2; // buttons to navigate through survey protected System.Web.UI.WebControls.ImageButton btnNext;  // the following class defines the container to store the survey data   [System.Serializable( )]   private class Survey   {   public int currentQuestion;   public Boolean response1;   public int response2;   }   // the following constant defines the variable used to store the survey   // data in the viewstate   private const String VS_SURVEY_DATA = "SurveyData";  //************************************************************************ // // 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) { Survey surveyData = null; // wire the next button click event this.btnNext.Click += new ImageClickEventHandler(this.btnNext_Click);  if (!Page.IsPostBack)   {   // initialize survey data   surveyData = new Survey( );   surveyData.currentQuestion = 1;   surveyData.response1 = false;   surveyData.response2 = -1;   // store the survey in the viewstate to use on the   // next submittal   ViewState.Add(VS_SURVEY_DATA, surveyData);   /// make the first question visible   pnlQuestion1.Visible = true;   pnlQuestion2.Visible = false;   pnlThankyou.Visible = false;   }  } // Page_Load //************************************************************************ // // ROUTINE: btnNext_Click // // DESCRIPTION: This routine provides the event handler for the next // button click event. //------------------------------------------------------------------------  private void btnNext_Click(Object sender,   System.Web.UI.ImageClickEventArgs e)   {   Survey surveyData = null;   // get the object from the viewstate with the survey data   surveyData = (Survey)(ViewState[VS_SURVEY_DATA]);   switch (surveyData.currentQuestion)   {   case 1:   // store answer to first question   if (radQuestion1.SelectedItem.Value == "0")   {   surveyData.response1 = false;   }   else   {   surveyData.response1 = true;   }   // increment the question number   surveyData.currentQuestion ++;   // store the survey in the viewstate to use on the   // next submittal   ViewState.Add(VS_SURVEY_DATA, surveyData);   // make 2nd question visible   pnlQuestion1.Visible = false;   pnlQuestion2.Visible = true;   break;   case 2:   // store answer to second question   surveyData.response2 = System.Convert.ToInt32(selQuestion2.Value);   // the survey is complete so store the answers per your   // applications required (database, etc.)   // make thank you panel visible   pnlQuestion2.Visible = false;   pnlThankyou.Visible = true;   btnNext.Visible = false;   break;   default:   // error case   break;   } // switch (surveyData.currentQuestion)   } // btnNext_Click  } // CH03MultiPageCS } 



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

Similar book on Amazon

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