CascadingDropDown jQuery Plugin for ASP.NET MVC

Cascading Drop Down is a jQuery plug-in that can be used by a select list to get automatic population using AJAX. The plug-in and a sample ASP.NET MVC project are attached at the bottom of this post.

image 
Usage
The code below shows two select lists :

<select id="customerID" name="customerID">
  <option value="ALFKI">Maria Anders</option>
  <option value="ANATR">Ana Trujillo</option>
  <option value="ANTON">Antonio Moreno</option>
</select>
 
<select id="orderID" name="orderID">
</select>

The following code causes the second list to auto populate when a customer is selected in the first list.

$("#orderID").CascadingDropDown("#customerID", '/Sales/AsyncOrders');

Internally, an AJAX post is made to ‘/Sales/AsyncOrders’ with the post body containing  customerID=[selectedCustomerID]. This executes the action AsyncOrders on the SalesController with signature AsyncOrders(string customerID).  The AsyncOrders method returns JSON which is then used to populate the select list. The JSON format expected is shown below :

[{
    "Text": "John",
    "Value": "10326"
},
{
    "Text": "Jane",
    "Value": "10801"
}]


Details

$(targetID).CascadingDropDown(sourceID, actionPath, settings)

  • targetID
    The ID of the select list that will auto populate. 
  • sourceID
    The ID of the select list, which, on change, causes the targetID to auto populate.
  • actionPath
    The url to post to

Options

  • promptText
    Text for the first item in the select list
    Default : -- Select --
  • loadingText
    Optional text to display in the select list while it is being loaded.
    Default : Loading..
  • errorText
    Optional text to display if an error occurs while populating the list
    Default: Error loading data.
  • postData
    Data you want posted to the url in place of the default
    Example :

    postData: function () {
        return { prefix: $('#txtPrefix').val(), customerID: $('#customerID').val() };
    }
    will cause prefix=foo&customerID=bar to be sent as the POST body.
    Default: A text string obtained by calling serialize on the sourceID

  • onLoading (event)
    Raised before the list is populated.
  • onLoaded (event)
    Raised after the list is populated, The code below shows how to “animate” the  select list after load.

Example using custom options:

$("#orderID").CascadingDropDown("#customerID", '/Sales/AsyncOrders',
{
    promptText: '-- Pick an Order--',
    onLoading: function () {
        $(this).css("background-color", "#ff3");
    },
    onLoaded: function () {
        $(this).animate({ backgroundColor: '#ffffff' }, 300);
    }
});


To return JSON from our action method, we use the Json ActionResult passing in an IEnumerable<SelectListItem>.

public ActionResult AsyncOrders(string customerID)
{
    var orders = repository.GetOrders(customerID).ToList().Select(a => new SelectListItem()
    {
        Text = a.OrderDate.HasValue ? a.OrderDate.Value.ToString("MM/dd/yyyy") : "[ No Date ]",
        Value = a.OrderID.ToString(),
    });
    return Json(orders);
}


jQuery Plug-in
Now hosted on GitHub

Sample Project using VS 2010 RTM (updated 5/21/2010)


Comments and suggestions are welcome.

Other Posts

5 Comments

  • Hi, this is an excellent script, exactly what I have been looking for. I have one small question, is it possible to reload the lists and select default values, basically be able to retain the selected values after a postback?

  • Very cool. Great work, I was looking something like this. You save me some time :)

  • nice one..very useful

  • $.fn.CascadingDropDown.defaults = {
    promptText: '-- 请选择 --',
    loadingText: '加载中...',
    errorText: '加载失败',
    postData: null,
    onLoading: null,
    onLoaded: null,
    dataType: 'json'
    }

    and


    success: function (data) {
    methods.reset();
    if (config.dataType == 'html') {
    $this.html(data);
    }
    else {
    var dataHtml = '';
    for (var item in data) {
    dataHtml += $(optionTag).attr("value", this.Value).text(this.Text)
    }
    this.html(dataHtml); ;
    }
    methods.loaded();
    $.isFunction(config.onLoaded) && config.onLoaded.call($this);
    },

  • Thank you so much for this awesome plugin. I do have a question - how would I have it load the target list initially based on the default selected I am setting on the source list? I'm thinking I would use the onLoaded option, but I'm not clear as to whether that fires on the source list or the target list... Your help is very much appreciated.
    Thank you so much,
    Donna

Comments have been disabled for this content.