Browser-enabled InfoPath form with a cascading dropdown from a SharePoint List

Posted: 7th October 2010 in Infopath, SharePoint

This is a challenge I’ve came across before: using the code behind of an InfoPath form to create a cascading dropdown. However, the last time i did this was around 3 years ago and all i really remembered was the fact that I had done it before!!!  So, I thought I’d blog it in case the situation comes up again, and to help anyone out there who is facing the same problem.

Okay first things, first. For this example I’ve used a SharePoint list

List Name: DropDownTypes

ColumnNames: DropDownType and DropDownSubTypes

Next, in InfoPath, create a data connection to receive data from the list.

image

image

And select the two columns, selecting the two columns mentioned above

image

Next, create an XML file with the following content and import it as a XML data source called DropDownOptions

<?xml version="1.0" encoding="UTF-8" ?>
<options>
  <option><value/></option>
  <option><value/></option>
</options>

Note: There are two option elements. This is to ensure the node is created as a repeating node

When importing the file, ensure that you use it as a form resource file

image

Now, create the nodes on the main data source to bind the values to and drag them on to the form canvas. This will create the two nodes as TextBoxes.

Change these to Drop-Down List Box by right clicking on the controls and choosing Change to from the context menu.

Okay, so far, so good. Now we need to retrieve the data. The type dropdown list is easy enough.

Just choose the DropDownList data source for the data source and DropDownType element as the entries.

image

 

Note: Make sure you select the “Show only entries with unique display names”

Preview the file you should now get the unique values populated in the DropDownType control.

To populate the DropDownSubTypes you need to add an event handler to the DropDownType control. To do this choose Programming –> Changed Event from the context menu of the control.

You should now be in Visual Studio for application with a newly create event handler DropDownType_Changed

 

Note: The reason this has to be done programmatically because you can’t use filters in browser enabled forms

We need  to populate the DropDownOptions data source with the values and bind it to the control.

Below is the Event handler to populate the control

Code Snippet
  1. public void DropDownType_Changed(object sender, XmlEventArgs e)
  2.         {
  3.             string dropDownType = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:DropDownType", NamespaceManager).Value;
  4.  
  5.             // clear the value of the subtype dropdown in case it has already been selected
  6.             MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:DropDownSubType", NamespaceManager).SetValue(string.Empty);
  7.             XPathNodeIterator subTypesIterator = DataSources["DropDownTypes"].CreateNavigator().Select("/dfs:myFields/dfs:dataFields/dfs:DropDownTypes[@DropDownType='" + dropDownType + "']/@DropDownSubType", NamespaceManager);
  8.             XPathNavigator optionsNode = DataSources["DropDownOptions"].CreateNavigator().SelectSingleNode("/options/option", NamespaceManager);
  9.             XPathNodeIterator optionsIterator = DataSources["DropDownOptions"].CreateNavigator().Select("options/option", NamespaceManager);
  10.             
  11.             // Clear the existing values
  12.             if (optionsIterator.Count > 1)
  13.             {
  14.                 for (int i = optionsIterator.Count; i > 1; i–)
  15.                 {
  16.                     DataSources["DropDownOptions"].CreateNavigator().SelectSingleNode("/options/option[" + i + "]", NamespaceManager).DeleteSelf();
  17.                 }
  18.             }
  19.  
  20.             // Populate the new values
  21.             while (subTypesIterator.MoveNext())
  22.             {
  23.                 XPathNavigator newNode = null;
  24.                 newNode = optionsNode.Clone();
  25.                 optionsNode.InsertAfter(newNode);
  26.                 newNode.SelectSingleNode("value", NamespaceManager).SetValue(subTypesIterator.Current.Value);
  27.             }
  28.  
  29.             int index = DataSources["DropDownOptions"].CreateNavigator().Select("/options/option", NamespaceManager).Count;
  30.             DataSources["DropDownOptions"].CreateNavigator().SelectSingleNode("options/option[" + index + "]", NamespaceManager).DeleteSelf();
  31.         }

Now all we need to do is to bind the SubType drop down list to the DropDownOptions data source

image

Hope this helps someone because it took me a while to suss it out. Enjoy!!

Advertisements
Comments
  1. suresh says:

    Thanks alot..its saved lot of my time…
    it seems its working for client based forms..it is taking time to load in child dropdowns in the browser enabled forms..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s