JavaScript Editor Javascript validator     Javascripts

Main Page


Previous Section Next Section

9.5 Binding Radio Buttons and Checkboxes

It is not uncommon to build your form dynamically; adding checkboxes, radio buttons, and other controls based on data extracted from a database. For example, you might like to add shipping methods (e.g., "first class," "next day," etc.) to the form. Typically you'd add these as radio buttons. To make the form flexible, you'd like to make it data-driven; getting the exact text for the radio buttons from a table in the database. That way, if you change from one delivery service to another, you do not need to change the web form; you just update the database and the form works.

As you saw in Chapter 3, ASP.NET offers a dynamic radio button control, RadioButtonList, which you can add to the form, deferring the content of the radio buttons (and even the number of buttons to create) until runtime. Begin the example with the following HTML source, which defines a RadioButtonList control named rbList:

<tr>
   <td>
      How should we ship?
   </td>
   <td>
      <asp:RadioButtonList 
      RepeatDirection="Horizontal" 
      id=rbList runat="server">
      </asp:RadioButtonList>
   </td>
</tr>

You'll look at how to fill the radio buttons with data in just a moment, but while you're building the form, add checkboxes to allow the customer to choose extras to go with his choice of books:

<tr>
   <td colspan="2">
      Please choose any "extras" you'd like:&nbsp;
      <asp:CheckBoxList 
      RepeatDirection="Horizontal"
      id="cbList" 
      runat="server"></asp:CheckBoxList>
   </td>
</tr>

Normally, you'd fill the radio buttons and the checkboxes with data from the database. Database access is covered in the next chapter; for now, you'll keep things simple by extracting the data from array lists.

Create a new ArrayList, shippingMethods, in the Page_Load function in the code-behind page. Add the various shipping alternatives that you would otherwise extract from the database (shown here in C# syntax):

ArrayList shippingMethods = new ArrayList(  );
shippingMethods.Add("3rd Class");
shippingMethods.Add("1st Class");
shippingMethods.Add("Ground");
shippingMethods.Add("2nd Day");
shippingMethods.Add("Next Day");

With this ArrayList in hand, you can bind to the radio button list created in the HTML page. This is done in two steps: first you set the data source for the radio button list to the Array List:

rbList.DataSource=shippingMethods;

Second, and as a separate step, call the radio buttons list object's DataBind method:

rbList.DataBind(  );

This separation is done for the reason explained earlier: by making the binding step explicit, you make the program more efficient, binding only when you invoke the DataBind method.

You'll do the same thing with the checkboxes, creating an ArrayList, setting the DataSource and calling DataBind:

ArrayList extras = new ArrayList(  );
extras.Add("Gift Wrap");
extras.Add("Gift Card");
extras.Add("Book Mark");
extras.Add("Autographed copy");
extras.Add("Source Code");
cbList.DataSource=extras;
cbList.DataBind(  );

That's all it takes; when the page is loaded, the checkboxes and radio buttons are created, based on the data in their data sources, as shown in Figure 9-4.

Figure 9-4. Binding to radio buttons and checkboxes
figs/pan2_0904.gif

The user interface design is crude at best, and making this look nice is left as an exercise for the reader. While you are at it, you'll want to add a required field validator (see Chapter 8) to ensure that the user does select at least one shipping method.

In this example, a button has been added to the form, and the autopostback attribute has been removed from the drop-down; these additions are shown in boldface in the HTML source in Example 9-5. The user selects a shipping method and zero or more of the "extras," and the user's choice is reflected in a label placed below the Submit button, as shown in Figure 9-5. The code to support this is in the Page_Load method in the code-behind page and is shown in boldface in the code-behind for both examples.

Figure 9-5. Displaying choices from data bound controls
figs/pan2_0905.gif

If the IsPostBack property is true, then the page has been submitted and you need to pick up the values from the radio buttons and checkboxes. This is accomplished by iterating the Items collection of the CheckBoxList and RadioButtonList controls. For example, to see which extras were chosen, you iterate the Items collection of cbList (the checkbox list on the form) as follows:

int chosen = 0;
StringBuilder extrasChosen = new StringBuilder(" with these extras:");

for (int i = 0; i < cbList.Items.Count; i++)
{
   if (cbList.Items[i].Selected)
   {
      chosen++;
      if (chosen > 1) 
         extrasChosen.Append(", ");
      extrasChosen.Append(cbList.Items[i].Text);

   }
}

The for loop iterates the items collection. Inside the for loop, each item is tested to see if its Selected property evaluates to true. The line:

if (cbList.Items[i].Selected)

can just as easily be written:

if (cbList.Items[i].Selected == true)

In C# these two lines are identical. Similarly, in VB.NET the line:

If cbList.Items(i).Selected Then

is identical to:

If cbList.Items(i).Selected = True Then

Each time a selected item is found, the local counter variable chosen is incremented, so that a comma can be placed after the first item. The extrasChosen StringBuilder object adds all the selected items so that they may be displayed in the lblMsg label.

Similar logic is applied to the radio buttons; however, you know in advance that only a single radio button can be selected:

for (int i = 0; i < rbList.Items.Count; i++)
   if (rbList.Items[i].Selected)
      shippingMethod.Append(rbList.Items[i].Text);

In C#, if a for or if statement is followed by a single statement, there is no need to use braces. As far as the for statement is concerned, the if statement is a single statement.

Example 9-5 is the complete .aspx file. Example 9-6 is the complete code-behind source file in VB .NET, and Example 9-7 is the code-behind in C#.

Example 9-5. aspx file for radio button and checkbox dynamic controls (with C# page directive)
<%@ Page language="c#" 
Codebehind="WebForm1.aspx.cs" 
AutoEventWireup="false" 
Inherits="BindRadioButtons.WebForm1" %>

<HTML>
  <HEAD>
<meta content="Internet Explorer 5.0" name=vs_targetSchema>
<meta content="Microsoft Visual Studio 7.0" name=GENERATOR>
<meta content=C# name=CODE_LANGUAGE>
  </HEAD>
<body MS_POSITIONING="GridLayout">
<form id=Form1 method=post runat="server">
<table>
  <tr>
    <td>Book </td>
    <td>
         <!-- the drop-down -->
         <asp:dropdownlist 
         id=ddlBooks 
         Runat="server" 
         DataValueField="ISBN" 
         DataTextField="Title">
         </asp:dropdownlist>
     </td>
   </tr>
   <! -- shipping method, radio buttons built dynamically -->   
   <tr>
      <td>
         How should we ship?
      </td>
      <td>
         <asp:radiobuttonlist 
         id=rbList runat="server" 
         RepeatDirection="Horizontal">
         </asp:radiobuttonlist>
      </td>
   </tr>
   <! -- extra features. checkboxes built dynamically -->      
   <tr>
      <td colspan="2">
         Please choose any "extras" you'd like:&nbsp;
         <asp:CheckBoxList 
         RepeatDirection="Horizontal" 
         id="cbList" 
         runat="server"></asp:CheckBoxList>
      </td>
   </tr>  
   <tr>
      <td colspan="2">
         <asp:Button id="Submit" runat="server" Text="Submit">
         </asp:Button>
      </td>
   </tr>    
   <tr>
      <!-- the label to display the selection -->
      <td colspan="2">
         <asp:Label ID="lblMsg" Runat="server" Text="" />
      </td>
   </tr>
  </TABLE></FORM>
  </body>
</HTML>
Example 9-6. VB .NET code-behind for dynamic radio buttons and checkboxes
Imports System.Collections
Imports System.Text

Public Class Example_9_7
  Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

  'This call is required by the Web Form Designer.
  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent(  )

  End Sub

  Protected WithEvents ddlBooks As System.Web.UI.WebControls.DropDownList
  Protected WithEvents rbList As System.Web.UI.WebControls.RadioButtonList
  Protected WithEvents cbList As System.Web.UI.WebControls.CheckBoxList
  Protected WithEvents Submit As System.Web.UI.WebControls.Button
  Protected WithEvents lblMsg As System.Web.UI.WebControls.Label

  Private designerPlaceholderDeclaration As System.Object

  Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) 
Handles MyBase.Init
    'CODEGEN: This method call is required by the Web Form Designer
    'Do not modify it using the code editor.
    InitializeComponent(  )
  End Sub

#End Region

  Public Class Book

    Private _Price As Double
    Private _Title As String
    Private _ISBN As String

    Public Sub New(ByVal thePrice As Double, _
      ByVal theTitle As String, ByVal theISBN As String)
      _Price = thePrice
      _Title = theTitle
      _ISBN = theISBN
    End Sub

    Public ReadOnly Property Price(  ) As Double
      Get
        Return _Price
      End Get
    End Property

    Public ReadOnly Property Title(  ) As String
      Get
        Return _Title
      End Get
    End Property

    Public ReadOnly Property ISBN(  ) As String
      Get
        Return _ISBN
      End Get
    End Property

  End Class

  Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load

    If Not IsPostBack(  ) Then

      ' create the array list
      Dim bookList As New ArrayList

      ' add all the books
      ' (formatted to fit in margins)
      bookList.Add(New Book(49.95F, "Programming ASP.NET", "100000000"))
      bookList.Add(New Book(49.95F, "Programming C#", "100000001"))
      bookList.Add(New Book(34.99F, "Teach Yourself C++ In 21 Days", _
        "067232072x"))
      bookList.Add(New Book(24.95F, "Teach Yourself C++ In 24 Hours", _ 
        "0672315165"))
      bookList.Add(New Book(12.99F, "TY C++ In 10 Minutes", "067231603X"))
      bookList.Add(New Book(24.95F, "C++ Unleashed", "1199000663"))
      bookList.Add(New Book(29.99F, "C++ From Scratch", "0789720795"))
      bookList.Add(New Book(39.99F, "XML From Scratch", "0789723166"))

      ' set the data source
      ddlBooks.DataSource = bookList

      ' bind to the data
      ddlBooks.DataBind(  )

      ' shippingMethods array list stands in for 
      ' data retrieved from database
      Dim shippingMethods As New ArrayList
      shippingMethods.Add("3rd Class")
      shippingMethods.Add("1st Class")
      shippingMethods.Add("Ground")
      shippingMethods.Add("2nd Day")
      shippingMethods.Add("Next Day")

      ' set the data source for the dynamic
      ' radio button list
      rbList.DataSource = shippingMethods

      ' bind the data
      rbList.DataBind(  )

      ' extras array list stands in for
      ' data retrieved from database
      Dim extras As New ArrayList
      extras.Add("Gift Wrap")
      extras.Add("Gift Card")
      extras.Add("Book Mark")
      extras.Add("Autographed copy")
      extras.Add("Source Code")

      ' set the data source for the 
      ' dynamic checkbox list
      cbList.DataSource = extras

      ' bind the data
      cbList.DataBind(  )

    Else

      ' string builders to hold text from controls
      Dim extrasChosen As New StringBuilder(" with these extras: ")
      Dim shippingMethod As New StringBuilder(" We will ship ")

      ' build up string of choices. if more than one choice
      ' make them comma delmited
      Dim chosen As Integer = 0
      Dim i As Integer = 0
      For i = 0 To cbList.Items.Count - 1

        ' if the item was selected
        If (cbList.Items(i).Selected = True) Then

          ' if this is not the first item
          ' add a comma after the previous
          ' before adding this one
          chosen += 1
          If (chosen > 1) Then extrasChosen.Append(", ")

          ' add the item to the string builder
          extrasChosen.Append(cbList.Items(i).Text)

        End If

      Next i

      ' find the selected shipping method and add it
      ' to the string builder
      For i = 0 To rbList.Items.Count - 1
        If (rbList.Items(i).Selected) Then
          shippingMethod.Append(rbList.Items(i).Text)
        End If
      Next i

      ' create the output text by concatenating the book title
      ' isbn, the selected items and the shipping method
      lblMsg.Text = "Selected: " & ddlBooks.SelectedItem.Text & _
        "(" & ddlBooks.SelectedItem.Value & ")" & _
        extrasChosen.ToString(  ) & _
        ".  " & shippingMethod.ToString(  ) & "."

    End If

  End Sub

End Class
Example 9-7. 7 C# code-behind for dynamic radio buttons and checkboxes
namespace BindRadioButtons
{
   using System;
   using System.Collections;
   using System.ComponentModel;
   using System.Data;
   using System.Drawing;
   using System.Text;  // for string builder
   using System.Web;
   using System.Web.SessionState;
   using System.Web.UI;
   using System.Web.UI.WebControls;
   using System.Web.UI.HtmlControls;

   public class WebForm1 : System.Web.UI.Page
   {
      protected System.Web.UI.WebControls.DropDownList ddlBooks;
      protected System.Web.UI.WebControls.RadioButtonList rbList;
      protected System.Web.UI.WebControls.CheckBoxList cbList;
      protected System.Web.UI.WebControls.Button Submit;
      protected System.Web.UI.WebControls.Label lblMsg;

      public WebForm1(  )
      {
         Page.Init += new System.EventHandler(Page_Init);
      }

      protected void Page_Init(object sender, EventArgs e)
      {
         //
         // CODEGEN: This call is required by the 
         // ASP.NET Windows Form Designer.
         //
         InitializeComponent(  );
      }

   #region Web Form Designer generated code
      /// <summary>
      ///   Required method for Designer support - do not modify
      ///   the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent(  )
      {    
         this.Load += 
            new System.EventHandler(this.Page_Load);

      }
   #endregion

      public class Book
      {
         private float price;
         private string title;
         private string isbn;

         public Book(float price, string title, string ISBN)
         {
            this.price = price;
            this.title = title;
            this.isbn = ISBN;
         }

         public float Price { get {return price;} }
         public string Title { get {return title;} }
         public string ISBN { get {return isbn;} }
      }

      private void Page_Load(object sender, System.EventArgs e)
      {
         if (! Page.IsPostBack)
         {
            // create the array list
            ArrayList bookList = new ArrayList(  );

            // add all the books
            // (formatted to fit in margins)
            bookList.Add(
               new Book(49.95f, "Programming ASP.NET",
                     "100000000"));
            bookList.Add(
               new Book(49.95f,"Programming C#",
                     "100000001"));
            bookList.Add(
               new Book(34.99f,"Teach Yourself C++ In 21 Days",
                     "067232072x"));
            bookList.Add(
               new Book(24.95f,"Teach Yourself C++ In 24 Hours",
                     "0672315165"));
            bookList.Add(
               new Book(12.99f,"TY C++ In 10 Minutes",
                     "067231603X"));
            bookList.Add(
               new Book(24.95f,"C++ Unleashed",
                     "1199000663"));
            bookList.Add(
               new Book(29.99f,"C++ From Scratch",
                     "0789720795"));
            bookList.Add(
               new Book(39.99f,"XML From Scratch",
                  "0789723166"));

            // set the data source
            ddlBooks.DataSource=bookList;

            // bind to the data
            ddlBooks.DataBind(  );

            // shippingMethods array list stands in for 
            // data retrieved from database
            ArrayList shippingMethods = new ArrayList(  );
            shippingMethods.Add("3rd Class");
            shippingMethods.Add("1st Class");
            shippingMethods.Add("Ground");
            shippingMethods.Add("2nd Day");
            shippingMethods.Add("Next Day");

            // set the data source for the dynamic
            // radio button list
            rbList.DataSource=shippingMethods;

            // bind the data
            rbList.DataBind(  );

            // extras array list stands in for
            // data retrieved from database
            ArrayList extras = new ArrayList(  );
            extras.Add("Gift Wrap");
            extras.Add("Gift Card");
            extras.Add("Book Mark");
            extras.Add("Autographed copy");
            extras.Add("Source Code");

            // set the data source for the 
            // dynamic checkbox list
            cbList.DataSource=extras;

            // bind the data
            cbList.DataBind(  );
         }
         else     // is post-back, form was submitted
         {
            // string builders to hold text from controls
            StringBuilder extrasChosen = 
               new StringBuilder(" with these extras: ");
            StringBuilder shippingMethod = 
               new StringBuilder(" We will ship ");

            // build up string of choices. if more than one choice
            // make them comma delmited
            int chosen = 0;
            for (int i = 0; i < cbList.Items.Count; i++)
            {
               // if the item was selected
               if (cbList.Items[i].Selected == true)
               {
                  // if this is not the first item
                  // add a comma after the previous
                  // before adding this one
                  chosen++;
                  if (chosen > 1) 
                     extrasChosen.Append(", ");

                  // add the item to the string builder
                  extrasChosen.Append(cbList.Items[i].Text);

               }
            }

            // find the selected shipping method and add it
            // to the string builder
            for (int i = 0; i < rbList.Items.Count; i++)
               if (rbList.Items[i].Selected)
                  shippingMethod.Append(rbList.Items[i].Text);

                            
            // create the output text by concatenating the book title
            // isbn, the selected items and the shipping method
            lblMsg.Text = "Selected: " + ddlBooks.SelectedItem.Text + 
               "(" + ddlBooks.SelectedItem.Value + ")" + extrasChosen + 
               ".  " + shippingMethod + ".";

         }  // end else
      }     // end page load
   }        // end class
}           // end namespace

There is complexity in the details here, but the essential idea remains quite simple: you bind a data source to a control. In this case, the data source was an ArrayList, but typically the data source will be created with data from a database (see Chapter 11). In this example, you bound the data to a radio button list and to a checkbox list so that you could dynamically create the controls based on the data in the data source.

    Previous Section Next Section


    JavaScript Editor Javascript validator     Javascripts 




    ©