Multiple Cascading Drop Down Lists

time to read 9 min | 1653 words

I recently found myself needing to handle a case where I had three drop down lists, and I needed to setup cascading relationship between those:

 ThreeDropDowns.png

Using the CascadingDropDown extender really make this a breeze, except that I had additional requirement, the benefits drop down should be filtered by both policy and insurance. So, when a policy is selected, all the matching insurance types are filled as well as all the matching benefits for the policy. When an insurance is selected, the benefits list should contains only the benefits for this insurance type.

At first I tried to simply setup a new extender from benefits to policies, that worked, until I selected a value from the insurance list, after which trying to unselect a value would leave me with a disabled drop down. After a bit of fumbling, I came up with this code, that runs on the onChanged client-side event on the Insurances drop down list:

function updateBenefitsDropDownIfDisabled()

{

    if($('<%=Insurances.ClientID %>').selectedIndex == 0)

    {

       setTimeout("updateBenefitsByPolicy();",1);

      }

}

The reason that I am using setTimeout here is that I want the updateBenefitsByPolicy to run after all the associated event hanlders for the event has run ( including the one that disabled it ). Here is how updateBenefitsByPolicy works:

function updateBenefitsByPolicy()

{

      var behaviors =  Sys.UI.Behavior.getBehaviors($('<%=Benefits.ClientID%>'));

      for(var i=0;i<behaviors.length;i++)

      {

            var behave = behaviors[i];

            if(behave._name == "CascadingDropDownBehavior" &&

                  behave._parentControlID == '<%=Policies.ClientID %>')

            {

                  behave._lastParentValues = null;

                  behave._clearItems();

                  var updating = new Option();

                  updating.text = '<asp:Literal runat="server" Text="<%$ Resources:App, Updating %>"/>';

                  addToDropDown(dropDown,updating);

                  behave._onParentChange(null,null);

            }

      }

}

It uses internal variabled from the CascadingDropDown behavior, so it is a hack, but it works. It cycles through the list of behaviors for this element, searching for a CascadingDropDown whose parent is the policies drop down, then it clear the cache (forces it to go back to the server) and manually force an update on the cascade behavior.

Not the most elegant code, but it works...