ASP.NET MVC – jQuery – Json.. Cascading Dropdown

I’m less interested in the ‘cascading dropdown’ part of this post , as I am in demonstrating how json and jquery can be your friends in the asp.net mvc world.

Let’s start by a description of the ‘problem’:  On populating a page, we need to query for a set of companies and display those to the user.  Upon selection of a company, we need to populate another dropdown of the banks associated to that company.  You can fill in the blanks for ‘companies’with ‘banks’ – basically a one to many.  In my situation, I use lazy loading and do not need to pull all the banks in when the page loads.

First let’s look at the ‘onLoad’ of the page via jQuery:
$(function () {
  $("#companies").change(function () {
    LoadBanks($("#companies").val());
    });
  });

I’ve simplified this from the code to show the essentials.  I’m handling the onChange of the companies drop down list, something like this:
Select Company: <%= Html.DropDownList("companies", new SelectList(Model, "Companyid", "Name"), string.Empty)%>
The Model is my list of ‘Company’ objects.  The value is the id and the text is the name.
From the above javascript, you’ll see that when the dropdown item is selected I will be passing the selected value – which is the id – to the LoadBanks function:

function LoadBanks(companyId) {
 $.ajax({
  type: "POST",
  url: BuildUrl("Company/LoadBanks"),
  data: ({ id: companyId }),
  dataType: "json",
  beforeSend: function () {
$.blockUI({ message: "Retrieving Banks..." });   //this is great plugin - 'blockUI'
},
success: function (positivePayBanks) {
  $("#positivePayBanks").find('option').remove();
  $banks = $("#positivePayBanks");
  $.each(positivePayBanks, function (i, bank) {
  if (i == 0) { $("#BankID").val(bank.BankID); }
   $banks.append('<option value="' + bank.BankID + '">' + bank.BankName + '</option>');
  });
$.unblockUI();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
  $.unblockUI();
  var errMsg = "<P>Error Loading: " + XMLHttpRequest.responseText + "<br/>";
  $("#status").html(errMsg).show("slow");
}
});
}

So, what is going on in this call?

type: "POST"
url: BuildUrl("Company/LoadBanks"),   <-- the BuildUrl is just a helper call - basically this is the REST call to the controller/action
data: ({ id: companyId }),   <-- this is the params being sent to the Action.  I'm passing the selected company id
dataType: "json",   <--  I'm saying that the returning data will be json.

Let’s step out of the javascript/html to just show how easy it is to serialize the list of banks to json in mvc:
This isn’t too exciting but here is the controller action for ‘LoadBanks’:

[HttpPost]    <-- I'm requiring this to be a post here
public ActionResult LoadBanks(string id) <--- this id will pick up the id passed in the ajax call above
{
  var positivePayBanks = _companyService.GetBanksByCompanyId(new Guid(id));
  return Json(positivePayBanks);
}

Pretty boring isn’t it?  The simplicity here is appreciate though as mvc includes a JsonResult that will take the list of banks and generate the json!
Here is the select html:

<select id="positivePayBanks" class="required"></select>

The meat here of the post is how we can take that resulting json data and ‘bind’ it to the bank dropdown:

success: function (positivePayBanks) {   <--- 'positivePayBanks' is the returning json data
  $("#positivePayBanks").find('option').remove();     <--- this clears it each time, as it will continue to just append if I don't first remove it!
  $banks = $("#positivePayBanks");
  $.each(positivePayBanks, function (i, bank) {    <--- the beauty of jQuery here is a nice foreach statement
   if (i == 0) { $("#BankID").val(bank.BankID); }    <-- I'm actually forced to set the id of the selected bank or the form post doesn't catch it.
   $banks.append('<option value="' + bank.BankID + '">' + bank.BankName + '</option>');   <-- append the results to the select
  });
$.unblockUI(); //unblock the UI
}

I left the blockUI in this sample because I want to remind those using ajax, that there is no control over the latency on the network – so rather than leave the user wondering what just happened, this gives a visible indicator.
For those new to Json, the part I like the best here is that jQuery will deserialize the json data into the ajax result:
(success: function (positivePayBanks))
Since this is a list of banks, we can use jQuery to loop through each one and it is represented as a bank object, which allows for the ‘bank.BankID’ and ‘bank.BankName’
Just as a finishing note, it is possible to just return a partialview with a Html.DropdownList , etc..  – however, by using Json , it greatly decreases the transmission over the wire.  Json is a perfect medium for keeping the data minimal, and as you can see it goes hand in hand with frameworks like jQuery.
One piece of this I do not like, is how I needed to then set the selected bankId to a hidden field.  I was able to get the value passed into the form collection on form post naturally.  If anyone has a trick for that- let me know  🙂
PS. I’m still looking for a good WordPress application to run on MacBook
Advertisements

2 thoughts on “ASP.NET MVC – jQuery – Json.. Cascading Dropdown

  1. Can you show me how to do the hidden form part – I need to get the value of the selected item in the second drop down and not sure how to do that?

    Thanks
    Gregor

    1. Have you tried just using
      $(“#nameofselect”).val(); ?

      ie.
      var seletedPosittivePayBank = $(“#positivePayBanks”).val();

      (An empty val() should return the value a populated val(xyz) should set it)

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