Cascading Drop Down Lists in SharePoint
Introduction
A common request is the ability to have one drop down list (the child) being filled after another one (the parent) has; this is usually called cascading drop down lists.
There are several solutions for this, most of what I’ve found use JavaScript. It isn’t required, and a very simple solution exists, both for SharePoint 2010 as well as 2013.
Set Up
First, let’s create two lists: Parent and Child. Connect the Child to the Parent through a lookup field that points to the Parent’s ID field and call this lookup Parent. Add some records to it.
SharePoint Designer
On SharePoint Designer create a new web part page. Find some space and add two DropDownList controls:
1: <asp:DropDownList runat="server" ID="parentList" DataSourceID="parentDataSource" DataTextField="Title" DataValueField="ID" AutoPostBack="true" Width="200px" />
2:
3: <br/>
4:
5: <asp:DropDownList runat="server" ID="childList" DataSourceID="childDataSource" DataTextField="Title" DataValueField="ID" Width="200px" EnableViewState="false"/>
Next, add two SPDataSource controls:
1: <SharePoint:SPDataSource runat="server" DataSourceMode="List" SelectCommand="<View></View>" ID="parentDataSource">
2: <SelectParameters>
3: <asp:Parameter Name="ListID" DefaultValue="{828362D7-E519-4522-86AF-DF90AC023719}"/>
4: </SelectParameters>
5: </SharePoint:SPDataSource>
6:
7: <SharePoint:SPDataSource runat="server" DataSourceMode="List" SelectCommand="<View><Query><Where><Eq><FieldRef Name="Parent"/><Value Type="Lookup">{parent}</Value></Eq></Where></Query></View>" ID="childDataSource">
8: <SelectParameters>
9: <asp:Parameter Name="ListID" DefaultValue="{F83375F4-D4EB-48AF-8CD9-5E773BC7692F}"/>
10: <asp:ControlParameter ControlID="parentList" PropertyName="SelectedValue" Name="parent" />
11: </SelectParameters>
12: </SharePoint:SPDataSource>
Pay attention to a couple of things:
-
We are retrieving lists from the same site, but it is possible to get them from different sites as well, just change the DataSourceMode property and the SelectCommand accordingly;
-
I am using the standard ID and Title columns, but you can use whatever you want;
-
If you give other name to the lookup field other than Parent, you need to change the SelectCommand property accordingly (FieldRef element);
-
You can give any name you like to the DropDownList controls, but if you change the name of the parent one, don’t forget to update the ControlID property of the ControlParameter in the child’s SPDataSource;
-
For editing the child SPDataSource’s SelectCommand property, you should use the Tag Properties window, because the XML there is not encoded;
-
Disable View State for the child DropDownList by setting EnableViewState to false;
-
Leave AutoPostBack set to true for the parent DropDownList, this causes the page to reload when the parent changes.
Improvements
If you prefer to have the parent DropDownList initially unselected, use the following markup instead:
1: <asp:DropDownList runat="server" ID="parentList" DataSourceID="parentDataSource" DataTextField="Title" DataValueField="ID" AutoPostBack="true" Width="200px" AppendDataBoundItems="true">
2: <asp:ListItem Selected="true" Text="" Value="-1"/>
3: </asp:DropDownList>
AppendDataBoundItems makes sure that any items added from a data source control are appended to any existing ones.
Another useful improvement would be to wrap all controls inside an UpdatePanel. This way, when the parent DropDownList changes, it won’t cause a full page postback.
Of course, you can have any number of nested DropDownList controls, just follow the same logic.