Recipe 4.4. Simulating Multipage Forms Problem


Problem

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

Solution

Create one ASP.NET page. Use a Wizard control with a WizardStep control containing the HTML for each of the "virtual" pages you wish to display. The output of a typical multipage form is shown in Figures 4-1, 4-2, 4-3, 4-4 through 4-5. Examples 4-10, 4-11 through 4-12 showthe .aspx and code-behind files for an application that implements this solution.

Figure 4-1. Multipage form output (Section 1.1)


Discussion

In classic ASP, a series of questions or prompts, such as those on a survey or wizard, is typically implemented using multiple ASP pages with each submitting to the next in turn. Because ASP.NET 2.0 allows you to submit a form to another page, this same approach can still be used; however, ASP.NET 2.0 provides a simpler approach using the Wizard control.

Figure 4-2. Multipage form output (Section 1.2)


Figure 4-3. Multipage form output (Section 1.2.3)


Figure 4-4. Multipage form output (Section 1.2.4)


Figure 4-5. Multipage form output (Section 1.3)


The Wizard control provides the infrastructure you need to present a series of virtual pages to the user including the requisite navigation controls for moving forward and backward in the series. The virtual pages are defined using a WizardStep control for each of the individual pages you want to present to the user. By defining the step type for the WizardStep controls (Start, Step, Finish, Complete, and Auto), the Wizard control will display the appropriate navigation buttons. The navigation buttons displayed for each step type are shown below.

Table 4-1.

WizardStep type

Navigation buttons displayed

Start

Next

Step

Previous, Next

Finish

Previous, Complete

Complete

None

Auto

Automatically generates the navigation buttons as required by the position of the WizardStep control in the collection of WizardSteps


The example solution we present here uses the Wizard control and a series of WizardStep controls to display a series of questions in a short survey.

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


In our example, the .aspx file contains one Wizard control and five WizardStep controls. The first WizardStep contains the first question ("Do you currently use ASP.NET 1.x?") along with a RadioButtonList control for the response. The second WizardStep control contains the second question ("How long have you been using ASP.NET 1.x?") along with a DropDownList control for the response. The third and fourth WizardStep controls are the same as the first and second steps with questions related to ASP.NET 2.0. The fifth WizardStep control contains a message thanking the user for taking the survey.

The Page_Load event handler in the code-behind initializes two arrays containing the possible answers to the questions and binds the data to the RadioButtonList and DropDownList controls in steps 1 through 4, as shown in Examples 4-11 (VB) and 4-12 (C#). We used this approach to reuse the data and to set the stage for potentially populating the available responses from a database.

We have implemented event handlers in the code-behind for the wizard's next and previous button click events to demonstrate the ability to skip questions as a function of the user's responses. In the event handler for the next button click event (wzSurvey_NextButtonClick), we check to see if the current step is for one of the "use" questions. If the user responds by indicating she has not used ASP.NET, there is no point in asking how long she has used the product, so we skip the next step using the wizard's MoveTo method.

 

'skip steps as a function of the users answers Select Case e.CurrentStepIndex Case 0 If ((rbStep1.SelectedIndex >= 0) AndAlso _ (rbStep1.SelectedItem.Text.Equals("No"))) Then 'user does not use ASP.NET 1.x so move to 2.0 question wzSurvey.MoveTo(step3) End If Case 2 If ((rbStep1.SelectedIndex >= 0) AndAlso _ (rbStep3.SelectedItem.Text.Equals("No"))) Then 'user does not use ASP.NET 2.0 so move to complete step wzSurvey.MoveTo(step5) End If Case Else 'nothing required End Select

// skip steps as a function of the users answers switch (e.CurrentStepIndex) { case 0: if ((rbStep1.SelectedIndex >= 0) && (rbStep1.SelectedItem.Text.Equals("No"))) { // user does not use ASP.NET 1.x so move to 2.0 question wzSurvey.MoveTo(step3); } break; case 2: if ((rbStep1.SelectedIndex >= 0) && (rbStep3.SelectedItem.Text.Equals("No"))) { // user does not use ASP.NET 2.0 so move to complete step wzSurvey.MoveTo(step5); } break; default: // nothing required break; }

In the wizard's previous button click event handler (wzSurvey_PreviousButtonClick), we do the same checks, but this time for the user navigating in the reverse direction.

When the final step is reached, the survey should be saved in your data store. We do this in the event handler for the ActiveStepChanged event by checking to see if the ActiveStepIndex is equal to the last step in the series.

 

'check to see if the complete step is the active step If (wzSurvey.ActiveStepIndex = wzSurvey.WizardSteps.Count - 1) Then 'survey is complete so production application should store the data 'in an applicable data store End If

// check to see if the complete step is the active step if (wzSurvey.ActiveStepIndex == wzSurvey.WizardSteps.Count - 1) { // survey is complete so production application should store the data // in an applicable data store }

The Wizard control has a Finish button click event that can be used to trigger your code to save the results; however, if your implementation of the Wizard control (like our example) allows the user to skip steps, it is possible the Finish step will never be displayed and the Finish button click event will not occur.


In addition to sequential navigation, the Wizard control provides the ability to perform direct navigation through the series of steps by displaying a sidebar with links to each step, as shown in Figure 4-6. The sidebar is enabled by setting the DisplaySideBar attribute of the Wizard control to true.

 <asp:Wizard  runat="server"    Css Width="75%" align="center"    HeaderText="ASP.NET Usage Survey"    HeaderStyle-Css    StepStyle-HorizontalAlign="Left"    StepStyle-VerticalAlign="Middle"    DisplaySideBar="true"    SideBarStyle-Css    OnNextButtonClick="wzSurvey_NextButtonClick"    OnPreviousButtonClick="wzSurvey_PreviousButtonClick"    OnActiveStepChanged="wzSurvey_ActiveStepChanged" > 

Figure 4-6. Wizard control with sidebar navigation


By using the style attributes for each of the sections of the Wizard control, almost everything about the Wizard control can be configured to match the look and feel of your application.

See Also

Recipe 4.2

Example 4-10. Simulating a multipage form (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master" AutoEventWireup="false" CodeFile="CH04SurveyDataVB1.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH04SurveyDataVB1" Title="Using the Wizard Control For Data Collection" %> <asp:Content  Runat="server" ContentPlaceHolder>  <div align="center" > Using the Wizard Control For Data Collection (VB)  </div>  <asp:Wizard  runat="server"  Css Width="75%" align="center"  HeaderText="ASP.NET Usage Survey"  HeaderStyle-Css  StepStyle-HorizontalAlign="Left"  StepStyle-VerticalAlign="Middle"  DisplaySideBar="false"  OnNextButtonClick="wzSurvey_NextButtonClick"  OnPreviousButtonClick="wzSurvey_PreviousButtonClick"  OnActiveStepChanged="wzSurvey_ActiveStepChanged" > <WizardSteps> <asp:WizardStep  runat="server" StepType="Start" Title="1.x Use"> <asp:Label  runat="server" Css Text="Do you currently use ASP.NET 1.x?" /> <asp:RadioButtonList  Runat="server" RepeatLayout="Flow" RepeatDirection="Horizontal" Css /> </asp:WizardStep> <asp:WizardStep  runat="server"    StepType="Step" Title="1.x Experience"> <asp:Label  runat="server"     Css Text="How long have you been using ASP.NET 1.x?" /> <asp:DropDownList  runat="server"     Css /> </asp:WizardStep> <asp:WizardStep  runat="server" StepType="Step" Title="2.0 Use"> <asp:Label  runat="server"  Css  Text="Do you currently use ASP.NET 2.0?" /> <asp:RadioButtonList  Runat="server"     RepeatLayout="Flow" RepeatDirection="Horizontal" Css /> </asp:WizardStep> <asp:WizardStep  runat="server"    StepType="Finish" Title="2.0 Experience"> <asp:Label  runat="server"   Css   Text="How long have you been using ASP.NET 2.0?" /> <asp:DropDownList  runat="server"  Css /> </asp:WizardStep> <asp:WizardStep  runat="server" Ste1pType="Complete" Title="Complete" > <asp:Label  runat="server" Css Text="Thank you for taking our survey" /> </asp:WizardStep> </WizardSteps>   </asp:Wizard> </asp:Content> 

Example 4-11. Simulating a multipage form (.vb)

 Option Explicit On Option Strict On Imports System.Web.UI.WebControls Namespace ASPNetCookbook.VBExamples ''' <summary> ''' This class provides the code behind for ''' CH04SurveyDataVB1.aspx  ''' </summary> Partial Class CH04SurveyDataVB1 Inherits System.Web.UI.Page '''******************************************************************** ''' <summary> ''' This routine provides the event handler for the page load event. It ''' is responsible for initializing the controls on the page. ''' </summary> ''' ''' <param name="sender">Set to the sender of the event</param> ''' <param name="e">Set to the event arguments</param> Protected Sub Page_Load(ByVal sender As Object, _    ByVal e As System.EventArgs) Handles Me.Load Dim yesNoSelections As ArrayList Dim experienceSelections As ArrayList If (Not Page.IsPostBack) Then 'build the arraylist with the yes/no responses yesNoSelections = New ArrayList() yesNoSelections.Add(New ListItem("Yes", "1")) yesNoSelections.Add(New ListItem("No", "0"))     'bind the yes/no data to the radio button lists in the questions rbStep1.DataSource = yesNoSelections rbStep1.DataTextField = "Text" rbStep1.DataValueField = "Value" rbStep1.DataBind() rbStep3.DataSource = yesNoSelections rbStep3.DataTextField = "Text" rbStep3.DataValueField = "Value" rbStep3.DataBind() 'build the arraylist with the experience responses experienceSelections = New ArrayList experienceSelections.Add(New ListItem("-- Select One --", "0")) experienceSelections.Add(New ListItem("0-6 Months", "1")) experienceSelections.Add(New ListItem("7-12 Months", "2")) experienceSelections.Add(New ListItem("13-24 Months", "3")) experienceSelections.Add(New ListItem("24+ Months", "4")) 'bind the experience data to the radio button lists in the questions ddStep2.DataSource = experienceSelections ddStep2.DataTextField = "Text" ddStep2.DataValueField = "Value" ddStep2.DataBind() ddStep4.DataSource = experienceSelections ddStep4.DataTextField = "Text" ddStep4.DataValueField = "Value" ddStep4.DataBind() End If End Sub 'Page_Load '''*********************************************************************** ''' <summary> ''' This routine provides the event handler for the wizard's next button ''' click event. It is responsible for altering the survey navigation as ''' as function of the answers provided ''' </summary> ''' ''' <param name="sender"></param> ''' <param name="e"></param> Protected Sub wzSurvey_NextButtonClick(ByVal sender As Object, _ ByVal e As WizardNavigationEventArgs)    'skip steps as a function of the users answers    Select Case e.CurrentStepIndex  Case 0     If ((rbStep1.SelectedIndex >= 0) AndAlso _     (rbStep1.SelectedItem.Text.Equals("No"))) Then   'user does not use ASP.NET 1.x so move to 2.0 question  wzSurvey.MoveTo(step3)     End If      Case 2         If ((rbStep1.SelectedIndex >= 0) AndAlso _         (rbStep3.SelectedItem.Text.Equals("No"))) Then   'user does not use ASP.NET 2.0 so move to complete step  wzSurvey.MoveTo(step5)     End If      Case Else 'nothing required     End Select   End Sub 'wzSurvey_NextButtonClick   '''**********************************************************************   ''' <summary>   ''' This routine provides the event handler for the wizard's prev button   ''' click event. It is responsible for altering the survey navigation as   ''' as function of the answers provided   ''' </summary>   '''   ''' <param name="sender"></param>   ''' <param name="e"></param>   Protected Sub wzSurvey_PreviousButtonClick(ByVal sender As Object, _   ByVal e As WizardNavigationEventArgs) 'skip steps as a function of the users answers Select Case e.CurrentStepIndex Case 2   If ((rbStep1.SelectedIndex >= 0) AndAlso _       (rbStep3.SelectedItem.Text.Equals("No"))) Then 'user does not use ASP.NET 2.0 so move to 1.x question wzSurvey.MoveTo(step1)   End If Case Else   'nothing required End Select   End Sub 'wzSurvey_PreviousButtonClick     '''***********************************************************************  ''' <summary>  ''' This routine provides the event handler for the wizard's active step  ''' changed event. It is responsible for determining if the survey is  ''' complete and storing the data in the data store.  ''' </summary>  '''  ''' <param name="sender"></param>  ''' <param name="e"></param>  Protected Sub wzSurvey_ActiveStepChanged(ByVal sender As Object, _  ByVal e As System.EventArgs)    'check to see if the complete step is the active step    If (wzSurvey.ActiveStepIndex = wzSurvey.WizardSteps.Count - 1) Then      'survey is complete so production application should store the data  'in an applicable data store    End If   End Sub  'wzSurvey_ActiveStepChanged  End Class 'CH04SurveyDataVB1 End Namespace 

Example 4-12. Simulating a multipage form (.cs)

 using System; using System.Collections; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples { /// <summary> /// This class provides the code behind for /// CH04SurveyDataCS1.aspx /// </summary> public partial class CH04SurveyDataCS1 : System.Web.UI.Page {   ///******************************************************************   /// <summary>   /// This routine provides the event handler for the page load event.   /// It is responsible for initializing the controls on the page.   /// </summary>   ///   /// <param name="sender">Set to the sender of the event</param>   /// <param name="e">Set to the event arguments</param>             protected void Page_Load(object sender, EventArgs e)   { ArrayList yesNoSelections; ArrayList experienceSelections; if (!Page.IsPostBack) { // build the arraylist with the yes/no responses yesNoSelections = new ArrayList(); yesNoSelections.Add(new ListItem("Yes", "1")); yesNoSelections.Add(new ListItem("No", "0")); // bind the yes/no data to the radio button lists in the questions rbStep1.DataSource = yesNoSelections; rbStep1.DataTextField = "Text"; rbStep1.DataValueField = "Value"; rbStep1.DataBind(); rbStep3.DataSource = yesNoSelections; rbStep3.DataTextField = "Text"; rbStep3.DataValueField = "Value"; rbStep3.DataBind(); // build the arraylist with the experience responses experienceSelections = new ArrayList(); experienceSelections.Add(new ListItem("-- Select One --", "0")); experienceSelections.Add(new ListItem("0-6 Months", "1")); experienceSelections.Add(new ListItem("7-12 Months", "2")); experienceSelections.Add(new ListItem("13-24 Months", "3")); experienceSelections.Add(new ListItem("24+ Months", "4")); // bind the experience data to the radio button lists in the questions ddStep2.DataSource = experienceSelections; ddStep2.DataTextField = "Text"; ddStep2.DataValueField = "Value"; ddStep2.DataBind(); ddStep4.DataSource = experienceSelections; ddStep4.DataTextField = "Text"; ddStep4.DataValueField = "Value"; ddStep4.DataBind();  }   } // Page_Load      ///*******************************************************************    /// <summary>  /// This routine provides the event handler for the wizard's next button  /// click event. It is responsible for altering the survey navigation as  /// as function of the answers provided  /// </summary>  ///  /// <param name="sender"></param>  /// <param name="e"></param>  protected void wzSurvey_NextButtonClick(Object sender,  WizardNavigationEventArgs e)  { // skip steps as a function of the users answers switch (e.CurrentStepIndex) { case 0:    if ((rbStep1.SelectedIndex >= 0) &&        (rbStep1.SelectedItem.Text.Equals("No")))         {       // user does not use ASP.NET 1.x so move to 2.0 question   wzSurvey.MoveTo(step3);         } break; case 2:   if ((rbStep1.SelectedIndex >= 0) &&              (rbStep3.SelectedItem.Text.Equals("No")))    {  // user does not use ASP.NET 2.0 so move to complete step  wzSurvey.MoveTo(step5);     } break; default:    // nothing required    break; } } // wzSurvey_NextButtonClick       ///*********************************************************************    /// <summary>    /// This routine provides the event handler for the wizard's prev button    /// click event. It is responsible for altering the survey navigation as    /// as function of the answers provided    /// </summary>    ///    /// <param name="sender"></param>    /// <param name="e"></param>    protected void wzSurvey_PreviousButtonClick(Object sender,    WizardNavigationEventArgs e)       {   // skip steps as a function of the users answers   switch (e.CurrentStepIndex)   {  case 2:     if ((rbStep1.SelectedIndex >= 0) &&     (rbStep3.SelectedItem.Text.Equals("No"))) {    // user does not use ASP.NET 2.0 so move to 1.x question    wzSurvey.MoveTo(step1); } break; default:   // nothing required   break;  }    } // wzSurvey_PreviousButtonClick   ///**********************************************************************   /// <summary>   /// This routine provides the event handler for the wizard's active step   /// changed event. It is responsible for determining if the survey is   /// complete and storing the data in the data store.   /// </summary>   ///   /// <param name="sender"></param>   /// <param name="e"></param>   protected void wzSurvey_ActiveStepChanged(Object sender, System.EventArgs e)   {     // check to see if the complete step is the active step if (wzSurvey.ActiveStepIndex == wzSurvey.WizardSteps.Count - 1) {       // survey is complete so production application should store the data       // in an applicable data store }   } // wzSurvey_ActiveStepChanged  } // CH04SurveyDataCS1 } 



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

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