Alot of developers who are only getting started with either jQuery and/or MVC wants to know how to create Cascading Dropdowns, and the infamous Auto-Complete function for textboxes.
In this article, I will describe how you too can achieve this with a few simple steps.
Cascade Dropdowns
So lets begin with Cascading Dropdowns.
You have a primary dropdown, and then based on the selection of the primary dropdown item, you want to populate the secondary dropdown accordingly. This can be achieved using MVC methods in combination with jQuery calls.
In the sample above, I have a dropdown called “Call Type”. Based on the Call Type selected, the Category list is then automatically filtered for user input.
Below is the cshtml snippet for the control UI:
<div class="span3"> @Html.Label("Call Type", new { @class = "label-bold" }) @Html.DropDownList("ViewerCallType", String.Empty) </div> <div class="span3"> @Html.Label("Category", new { @class = "label-bold" }) @Html.DropDownList("CommentCategory", String.Empty) </div>
To handle the select event of the Primary Dropdown, add a delegate to the ‘onchange’ event as below:
$("#ViewerCallType").change(function (e) { $.getJSON("/Home/GetCommentCategory", { 'ViewerCallType': $("#ViewerCallType > option:selected").attr("value") }, function (data) { var items = "---------------------"; $.each(data, function (i, category) { items += " " + category.text + " "; }); $("#CommentCategory").html(items); }); });
The code above will call the “GetcommentCategory” action in the Home controller class, and pass in the selected CallerType value. On return, the JSON data is traversed. The option tags are generated, and then the list is assigned to the CommentCategory control. Next let’s take a look at the controller.
The Controller
public JsonResult GetCommentCategory(string ViewerCallType) { var list = (from i in db.MyCategoryTable where i.CallType.Equals(ViewerCallType, StringComparison.CurrentCultureIgnoreCase) select new { value = i.MyValue, text = i.MyText }).OrderBy(i => i.value); return Json(list, JsonRequestBehavior.AllowGet); }
Pretty easy right? Using Linq, make a query to the data table, filtering by the selected Call Type value that is passed in as the first parameter. On exit, simply return the list in the JSON format by using the Json() method.
Auto-Completes
Adding Autocomplete to a text is just as easy!
So say you have the following textbox to display a list of email recipients.
This can be a BIG list, so it’s nice to filter the list.
Firstly, let’s create the textbox:
@Html.Label("Recipient", new { @class = "label-bold" }) @Html.TextBox("Recipient", Model.Recipient)
Then.. we can add the jQuery code to turn this basic input control into a jQuery auto-complete control:
$('#Recipient).autocomplete( { source: "/Home/GetRecipients", minLength: 3, select: function (event, ui) { $('#Recipient).val(ui.item.value); } });
You will need to download and link the autocomplete control JS files as appropriate: http://jqueryui.com/autocomplete/
The above code tells jQuery to execute the action “GetRecipients” in the Home controller, only when there are 3 characters or more entered into the text box (this is restrict network traffic and prevent overloads). On select of an item, the value of the selected item will be assigned to the auto-complete textbox.
Here’s the controller method:
public JsonResult GetRecipients(string term) { var list = (from i in db.Employees where ((i.FirstName.StartsWith(term) || i.LastName.StartsWith(term)))) select new { value = i.DisplayName, id = i.EmailAddress }).OrderBy(i => i.value).Take(20); return Json(list, JsonRequestBehavior.AllowGet); }
There you have it. Hope this helped! 🙂
February 5th, 2014 on 8:11 AM
I copied your Cascade Dropdowns code but was unable to get it to work. Within the script function you refer to category: “i, category” and later “category.text” (though not “category.value”). You don’t seem to have used category as a variable anywhere else, with the exception of the label tag. Just trying to understand where my code is going wrong.
February 5th, 2014 on 9:33 AM
Hi Chelle, Sorry to hear you’re having issues with your code.
I’m assuming you are referring to the script’s onchange event for the ViewerCallType dropdown?
If so, the onsuccess delegate function simple loops through all the entities returned by the service call to /Home/GetCommentCategory/ and uses the category.text property of that object as the display value for the dropdown.
If you are able to debug your code, try to put a breakpoint right before the action method of /Home/GetCommentCategory/ returns and check out the data.
If that doesnt help, can you post your error message to see if we can isolate the bug?
Thanks.
Jason