Great Article On Cascading DropDown List and jQuery

Not to poach a blog post/article you need to go to www.mikesdotnetting.com and read his great article on Cascading DropDownLists with jQuery and ASP.NET.

http://www.mikesdotnetting.com/Article/97/Cascading-DropDownLists-with-jQuery-and-ASP.NET

After I read this article I decided to recreate it and build in some features of my own.  The feature I wanted most was a way to preserve the values on post back so that I didn't have to reload the list.  Also I wanted to be able to select the car (radio button) and then post that as well. The approach I took was using hidden variables (<asp:HiddenField />) that got updated as the dropdown list got changed and edited. Then on postback reload the lists based off of the values. If anyone has suggestions to better ways to accomplish the same thing I am listening. Here is the resulting code.

   1: <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
   2:     <script language="javascript" type="text/javascript" src='<%=ResolveClientUrl("~/") %>resources/scripts/jquery.selectboxes.min.js' ></script>
   1:  
   2:     <script type="text/javascript">
   3:         $(function() {
   4:             $('#<%= this.ddlMake.ClientID %>').change(function() {
   5:                 $("#<%= this.hidModel.ClientID %>").val('');
   6:                 $("#<%= this.hidColor.ClientID %>").val('');
   7:                 $("#<%= this.hidSelect.ClientID %>").val('');
   8:                 $('#output').empty();
   9:                 getModels();
  10:             });
  11:             $('#<%= this.ddlModel.ClientID %>').change(function() {
  12:                 $("#<%= this.hidModel.ClientID %>").val($(this).val());
  13:                 $("#<%= this.hidColor.ClientID %>").val('');
  14:                 $("#<%= this.hidSelect.ClientID %>").val('');
  15:                 $('#output').empty();
  16:                 getColors();
  17:             });
  18:             $('#<%= this.ddlColor.ClientID %>').change(function() {
  19:                 $("#<%= this.hidColor.ClientID %>").val($(this).val());
  20:                 $("#<%= this.hidSelect.ClientID %>").val('');
  21:                 $('#output').empty();
  22:                 getCarListByColor();
  23:             });
  24:  
  25:             $('#<%= this.ddlModel.ClientID %>').attr('disabled', true);
  26:             $('#<%= this.ddlColor.ClientID %>').attr('disabled', true);
  27:  
  28:             if ($('#<%= this.ddlMake.ClientID %>').val() != '') {
  29:                 getModels();
  30:             }
  31:  
  32:             $(".carSelect").live("click", function() {
  33:                 $("#<%= this.hidSelect.ClientID %>").val($(this).val());
  34:             });
  35:         });
  36:  
  37:         function getModels() {
  38:              $.ajax({
  39:                 type: "POST",
  40:                 url: "WebServices/CarService.asmx/GetCarsByModel",
  41:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "'}",
  42:                 contentType: "application/json; charset=utf-8",
  43:                 dataType: "json",
  44:                 success: function(response) {
  45:                     var models = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  46:                     $('#<%= this.ddlModel.ClientID %>').attr('disabled', false).removeOption(/./).addOption('', ' -- Select Model -- ');
  47:                     $('#<%= this.ddlColor.ClientID %>').attr('disabled', true).removeOption(/./);
  48:                     for (var i = 0; i < models.length; i++) {
  49:                         var val = models[i];
  50:                         var text = models[i];
  51:                         $('#<%= this.ddlModel.ClientID %>').addOption(val, text, (val == $("#<%= this.hidModel.ClientID %>").val()) ? true : false);
  52:                     }
  53:                     if ($('#<%= this.ddlModel.ClientID %>').val() != '')
  54:                     { 
  55:                         getColors();
  56:                     }
  57:                 }
  58:             });
  59:         }
  60:  
  61:         function getColors() {
  62:             $.ajax({
  63:                 type: "POST",
  64:                 url: "WebServices/CarService.asmx/GetCarsByColor",
  65:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "', model: '" + $('#<%= this.hidModel.ClientID %>').val() + "'}",
  66:                 contentType: "application/json; charset=utf-8",
  67:                 dataType: "json",
  68:                 success: function(response) {
  69:                     var Colors = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  70:                     $('#<%= this.ddlColor.ClientID %>').attr('disabled', false).removeOption(/./).addOption('', ' -- Select Color -- ');
  71:                     for (var i = 0; i < Colors.length; i++) {
  72:                         var val = Colors[i];
  73:                         var text = Colors[i];
  74:                         $('#<%= this.ddlColor.ClientID %>').addOption(val, text, (val == $("#<%= this.hidColor.ClientID %>").val()) ? true : false);
  75:                     }
  76:                     if ($('#<%= this.ddlColor.ClientID %>').val() != '') {
  77:                         getCarListByColor();
  78:                     }
  79:                 }
  80:             });
  81:         }
  82:  
  83:         function getCarListByColor() {
  84:             $.ajax({
  85:                 type: "POST",
  86:                 url: "WebServices/CarService.asmx/GetCarListByColor",
  87:                 data: "{make: '" + $('#<%= this.ddlMake.ClientID %>').val() + "', " + "model: '" + $('#<%= this.hidModel.ClientID %>').val() + "', " + "color: '" + $('#<%= this.hidColor.ClientID %>').val() + "'}",
  88:                 contentType: "application/json; charset=utf-8",
  89:                 dataType: "json",
  90:                 success: function(response) {
  91:                     var cars = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
  92:                     $('#output').empty();
  93:                     for (var i = 0; i < cars.length; i++) {
  94:                         var checked = ($('#<%= this.hidSelect.ClientID %>').val() == cars[i].ID) ? 'checked' : '';
  95:                         $('#output').append('<p><input class="carSelect" ' + checked + ' type="radio" name="car" value="' + cars[i].ID + '" /><strong>' + cars[i].Make + ' ' +
  96:                               cars[i].Model + '</strong><br /> Year: ' +
  97:                               cars[i].Year + '<br />Doors: ' +
  98:                               cars[i].Doors + '<br />Color: ' +
  99:                               cars[i].Color + '<br />Mileage: ' +
 100:                               cars[i].Mileage + '<br />Price: $' +
 101:                               cars[i].Price + '</p>');
 102:                     }
 103:                 }
 104:             });
 105:         }
 106:     
</script>
   3:  
   4: </asp:Content>
   5: <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
   6:     <div>
   7:         <div>
   8:             <p>
   9:                 <label>
  10:                     Please choose a Make:</label><br />
  11:                 <asp:DropDownList ID="ddlMake" runat="server" />
  12:             </p>
  13:         </div>
  14:         <div>
  15:             <p>
  16:                 <label>
  17:                     Please choose a Model:</label><br />
  18:                 <select ID="ddlModel" runat="server" />
  19:             </p>
  20:         </div>
  21:         <div>
  22:             <p>
  23:                 <label>
  24:                     Please choose a Color:</label><br />
  25:                 <select ID="ddlColor" runat="server" />
  26:             </p>
  27:         </div>
  28:         <div>
  29:             <asp:Button ID="btnSubmit" runat="server" Text="Submit" 
  30:                 onclick="btnSubmit_Click" />
  31:         </div>
  32:         <div id="output">
  33:         </div>
  34:     </div>
  35:     <asp:Label runat="server" ID="lblResults" />
  36:     <asp:HiddenField runat="server" ID="hidModel" />
  37:     <asp:HiddenField runat="server" ID="hidSelect" />
  38:     <asp:HiddenField runat="server" ID="hidColor" />
  39: </asp:Content>

In order to capture the car selected on postback I added an ID to each car. I needed to adjust the car object by adding an ID field.  Here is the resulting code.

   1: using System;
   2: using System.Web;
   3: using System.Web.Services;
   4: using System.Web.Services.Protocols;
   5: using System.Web.Script.Services;
   6: using System.Collections.Generic;
   7: using System.Linq;
   8:  
   9: public class Car
  10: {
  11:     public int ID;
  12:     public string Make;
  13:     public string Model;
  14:     public int Year;
  15:     public int Doors;
  16:     public string Color;
  17:     public float Price;
  18:     public int Mileage;
  19: }
  20:  
  21: /// <summary>
  22: /// Summary description for CarService
  23: /// </summary>
  24: [WebService(Namespace = "http://tempuri.org/")]
  25: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  26: [ScriptService]
  27: public class CarService : WebService
  28: {
  29:     List<Car> Cars = new List<Car>{
  30:     new Car{ID=1,Make="Audi",Model="A4",Year=1995,Doors=4,Color="Red",Price=2995f,Mileage=122458},
  31:     new Car{ID=2,Make="Ford",Model="Focus",Year=2002,Doors=5,Color="Black",Price=3250f,Mileage=68500},
  32:     new Car{ID=3,Make="BMW",Model="5 Series",Year=2006,Doors=4,Color="Grey",Price=24950f,Mileage=19500},
  33:     new Car{ID=4,Make="Renault",Model="Laguna",Year=2000,Doors=5,Color="Red",Price=3995f,Mileage=82600},
  34:     new Car{ID=5,Make="Toyota",Model="Previa",Year=1998,Doors=5,Color="Green",Price=2695f,Mileage=72400},
  35:     new Car{ID=6,Make="Mini",Model="Cooper",Year=2005,Doors=2,Color="Grey",Price=9850f,Mileage=19800},
  36:     new Car{ID=7,Make="Mazda",Model="MX 5",Year=2003,Doors=2,Color="Silver",Price=6995f,Mileage=51988},
  37:     new Car{ID=8,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Red",Price=3759f,Mileage=50000},
  38:     new Car{ID=9,Make="Honda",Model="Accord",Year=1997,Doors=4,Color="Silver",Price=1995f,Mileage=99750},
  39:     new Car{ID=10,Make="Audi",Model="A6",Year=2005,Doors=5,Color="Silver",Price=22995f,Mileage=25400},
  40:     new Car{ID=11,Make="Jaguar",Model="XJS",Year=1992,Doors=4,Color="Green",Price=3450,Mileage=92000},
  41:     new Car{ID=12,Make="Jaguar",Model="X Type",Year=2006,Doors=4,Color="Grey",Price=9950f,Mileage=17000},
  42:     new Car{ID=13,Make="Renault",Model="Megane",Year=2007,Doors=5,Color="Red",Price=8995f,Mileage=8500},
  43:     new Car{ID=14,Make="Peugeot",Model="406",Year=2003,Doors=4,Color="Grey",Price=3450f,Mileage=86000},
  44:     new Car{ID=15,Make="Mini",Model="Cooper S",Year=2008,Doors=2,Color="Black",Price=14850f,Mileage=9500},
  45:     new Car{ID=16,Make="Mazda",Model="5",Year=2006,Doors=5,Color="Silver",Price=6940f,Mileage=53500},
  46:     new Car{ID=17,Make="Vauxhall",Model="Vectra",Year=2007,Doors=5,Color="White",Price=13750f,Mileage=31000},
  47:     new Car{ID=18,Make="Ford",Model="Puma",Year=1998,Doors=3,Color="Silver",Price=2995f,Mileage=84500},
  48:     new Car{ID=19,Make="Ford",Model="Ka",Year=2004,Doors=3,Color="Red",Price=2995f,Mileage=61000},
  49:     new Car{ID=20,Make="Ford",Model="Focus",Year=2007,Doors=5,Color="Blue",Price=9950f,Mileage=19000},
  50:     new Car{ID=21,Make="BMW",Model="3 Series",Year=2001,Doors=4,Color="White",Price=5950f,Mileage=98000},
  51:     new Car{ID=22,Make="Citroen",Model="C5",Year=2005,Doors=5,Color="Silver",Price=5995f,Mileage=38400},
  52:     new Car{ID=23,Make="Toyota",Model="Corolla T3",Year=2004,Doors=5,Color="Blue",Price=5995f,Mileage=71000},
  53:     new Car{ID=24,Make="Toyota",Model="Yaris",Year=2005,Doors=3,Color="Grey",Price=5350f,Mileage=39000},
  54:     new Car{ID=25,Make="Porsche",Model="911",Year=2003,Doors=2,Color="Red",Price=16995f,Mileage=88000},
  55:     new Car{ID=26,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Red",Price=5759f,Mileage=49000},
  56:     new Car{ID=27,Make="Honda",Model="Accord",Year=1996,Doors=4,Color="Black",Price=1995f,Mileage=105000},
  57:     new Car{ID=28,Make="Audi",Model="A3 Avant",Year=2005,Doors=5,Color="Blue",Price=12995f,Mileage=22458},
  58:     new Car{ID=29,Make="Ford",Model="Mondeo",Year=2007,Doors=5,Color="Gold",Price=12250f,Mileage=8500},
  59:     new Car{ID=30,Make="BMW",Model="1 Series",Year=2006,Doors=4,Color="Black",Price=16950f,Mileage=19500},
  60:     new Car{ID=31,Make="Renault",Model="Clio",Year=2005,Doors=3,Color="Red",Price=5995f,Mileage=32600},
  61:     new Car{ID=32,Make="Toyota",Model="Verso",Year=2008,Doors=5,Color="White",Price=12995f,Mileage=5800},
  62:     new Car{ID=33,Make="Mini",Model="Cooper",Year=2003,Doors=2,Color="Black",Price=7950f,Mileage=36800},
  63:     new Car{ID=34,Make="Mazda",Model="6",Year=2007,Doors=4,Color="Blue",Price=16995f,Mileage=11300},
  64:     new Car{ID=35,Make="Ford",Model="Mondeo",Year=2004,Doors=5,Color="Green",Price=8759f,Mileage=66000},
  65:     new Car{ID=36,Make="Honda",Model="Civic",Year=1997,Doors=4,Color="Grey",Price=1995f,Mileage=99750},
  66:     new Car{ID=37,Make="Audi",Model="Q7",Year=2005,Doors=5,Color="Black",Price=22995f,Mileage=25400},
  67:     new Car{ID=38,Make="Jaguar",Model="XK8",Year=1992,Doors=4,Color="Blue",Price=3450,Mileage=92000},
  68:     new Car{ID=39,Make="Jaguar",Model="S Type",Year=2006,Doors=4,Color="Red",Price=9950f,Mileage=17000},
  69:     new Car{ID=40,Make="Renault",Model="Megane",Year=2007,Doors=5,Color="Yellow",Price=8995f,Mileage=8500},
  70:     new Car{ID=41,Make="Peugeot",Model="406",Year=2003,Doors=4,Color="White",Price=3450f,Mileage=86000},
  71:     new Car{ID=42,Make="Mini",Model="Cooper",Year=2008,Doors=2,Color="Red",Price=14850f,Mileage=9500},
  72:     new Car{ID=43,Make="Mazda",Model="5",Year=2006,Doors=5,Color="White",Price=6940f,Mileage=53500},
  73:     new Car{ID=44,Make="Vauxhall",Model="Vectra",Year=2007,Doors=5,Color="Blue",Price=13750f,Mileage=31000},
  74:     new Car{ID=45,Make="Ford",Model="Puma",Year=1998,Doors=3,Color="Red",Price=2995f,Mileage=84500},
  75:     new Car{ID=46,Make="Ford",Model="Puma",Year=2004,Doors=3,Color="Red",Price=2995f,Mileage=61000},
  76:     new Car{ID=47,Make="Ford",Model="Focus",Year=2007,Doors=5,Color="Grey",Price=9950f,Mileage=19000},
  77:     new Car{ID=48,Make="BMW",Model="3 Series",Year=2001,Doors=4,Color="Red",Price=5950f,Mileage=98000},
  78:     new Car{ID=49,Make="Citroen",Model="C5",Year=2005,Doors=5,Color="Yellow",Price=5995f,Mileage=38400},
  79:     new Car{ID=50,Make="Toyota",Model="Corolla T3",Year=2004,Doors=5,Color="Red",Price=5995f,Mileage=71000},
  80:     new Car{ID=51,Make="Toyota",Model="Yaris",Year=2005,Doors=3,Color="Black",Price=5350f,Mileage=39000},
  81:     new Car{ID=52,Make="Porsche",Model="911",Year=2003,Doors=2,Color="White",Price=16995f,Mileage=88000},
  82:     new Car{ID=53,Make="Ford",Model="Fiesta",Year=2004,Doors=3,Color="Grey",Price=5759f,Mileage=49000},
  83:     new Car{ID=54,Make="Honda",Model="Accord",Year=1996,Doors=4,Color="Green",Price=1995f,Mileage=105000}
  84:     };
  85:  
  86:     [WebMethod]
  87:     public List<Car> GetCarsByDoors(int doors)
  88:    {
  89:         var query = from c in Cars
  90:                     where c.Doors == doors
  91:                     select c;
  92:         return query.ToList();
  93:     }
  94:  
  95:     [WebMethod]
  96:     public List<Car> GetAllCars()
  97:    {
  98:         return Cars;
  99:     }
 100:  
 101:     [WebMethod]
 102:     public List<string> GetCarMakes()
 103:    {
 104:         var query = (from c in Cars
 105:                      orderby c.Make
 106:                      select c.Make).Distinct();
 107:         return query.ToList();
 108:     }
 109:  
 110:     [WebMethod]
 111:     public List<string> GetCarsByModel(string make)
 112:    {
 113:         var query = (from c in Cars
 114:                      where c.Make == make
 115:                      orderby c.Model
 116:                      select c.Model).Distinct();
 117:         return query.ToList();
 118:     }
 119:  
 120:     [WebMethod]
 121:     public List<string> GetCarsByColor(string make, string model)
 122:    {
 123:         var query = (from c in Cars
 124:                      where c.Make == make && c.Model == model
 125:                      orderby c.Color
 126:                      select c.Color).Distinct();
 127:         return query.ToList();
 128:     }
 129:  
 130:     [WebMethod]
 131:     public List<Car> GetCarListByColor(string make, string model, string color)
 132:    {
 133:         var query = from c in Cars
 134:                     where (c.Make == make &&
 135:                     c.Model == model &&
 136:                     c.Color == color)
 137:                     select c;
 138:         return query.ToList();
 139:     }
 140: }

Please note that I renamed colour to color throughout my project and I store my webservice (asmx) page in a folder called WebServcies. Also I am using a MasterPage so I used the $("#<%= this.<CONTROLID>.ClientID %>") name throught out the code.

6 Comments

Comments have been disabled for this content.