Thursday, January 3, 2013

Cascading Dropdown Boxes with Data coming from XML

A friend from my days at Blackboard sent me the following code mockup and asked me how to make it work.

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:XmlDataSource ID="XmlDataSource1" DataFile="FeatureRequestDatasource.xml" runat="server" XPath="product/feature" ></asp:XmlDataSource>
<asp:XmlDataSource ID="XmlDataSource2" DataFile="FeatureRequestDatasource.xml" runat="server" XPath="product/feature/area"></asp:XmlDataSource>
<asp:XmlDataSource ID="XmlDataSource3" DataFile="FeatureRequestDatasource.xml" runat="server" ></asp:XmlDataSource>
   <h3>Sample Feedback Submit Form</h3>
       <div>
       Product Feature <asp:DropDownList ID="DropDownList1" 
               DataSourceID="XmlDataSource1" DataValueField="value" DataTextField="text"  
               Width="250" runat="server" 
               >         
       </asp:DropDownList><p />
       Feature Area <asp:DropDownList ID="DropDownList2" 
                   DataSourceID="XmlDataSource2" DataValueField="value" DataTextField="text"  
                   Width="300" runat="server" 
                   >
        </asp:DropDownList><p />
       Feature Subarea <asp:DropDownList ID="DropDownList3" DataSourceID="XmlDataSource3" DataValueField="value" DataTextField="text" Width="400" runat="server">
        </asp:DropDownList><p />
       <span style="vertical-align:top">Comments</span> <asp:TextBox ID="TextBox1"  TextMode="MultiLine" width="400" Height="200" runat="server"></asp:TextBox><p />
       Upload JPG screen shot&nbsp;&nbsp;<asp:FileUpload ID="FileUpload1" runat="server" /><p />
        <input id="Submit1" type="submit" value="submit" /><p />
      </div>
</asp:Content>

An example of the data source XML is shown below:

<product>
  <feature value="01" text="Case Management" >
    <area value="011" text="Opening a Case" />
    <area value="012" text="Closing a Case" />
    <area value="013" text="Re-Assigning a Case" >
      <subarea value="011" text="To Legal" />
      <subarea value="012" text="To Supervisor" />
    </area>
  </feature>

My initial take would be to use an ObjectDataSource that loads the XML instead because it allow me to use Control Parameters for Selects.

However, I thought it would be fun to try making the XMLDataSource work… and it was not much effort. An example of the result is shown below.

 

image

First, I needed to change the page a little by adding to the first two dropdowns

AutoPostBack="True" onselectedindexchanged="DropDownList1_SelectedIndexChanged" 
AutoPostBack="True" onselectedindexchanged="DropDownList2_SelectedIndexChanged" 

The rest is in the code behind. We need to do a little “pushing” on the initial load to get the initial cascade working

protected void Page_Load(object sender, EventArgs e)
{
    if(! IsPostBack)
    {
        DropDownList1.DataBind();
        DropDownList1_SelectedIndexChanged(sender, e);
        DropDownList2.DataBind();
        DropDownList2_SelectedIndexChanged(sender, e);
    }
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
    XmlDataSource2.XPath = String.Format("product/feature[@value='{0}']/area",DropDownList1.SelectedValue);
}
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
    XmlDataSource3.XPath = String.Format("product/feature[@value='{0}']/area[@value='{1}']/subarea", DropDownList1.SelectedValue, DropDownList2.SelectedValue);
}
That’s it!

1 comment: