Imagine that you have an E-Commerce site and you would like the user to drill down into the attributes of a product to help the user find exactly what they need. You display a dropdown list of product colors. Each time a user selects a new color, a dropdown list displaying products available in that color is populated. In this demo, I've created a small application demonstrating on how to use ASP.net MVC 1.0 framework and JQuery to complete the task.
1-Data Models
First, for demonstration purposes and easy download, I created two Model Data sources without the use of SQL. Colors and Products:
Models/Colors.cs using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace JQueryJsonSelectDemo.Models
{
public class Color
{
public string ColorName { get; set; }
public string ColorCode { get; set; }
public int ColorId { get; set; }
public static IQueryable<Color> GetColorDataList()
{
return new List<Color>()
{
new Color { ColorName = "Blue", ColorCode = "BL", ColorId = 1},
new Color { ColorName = "Red", ColorCode = "RD", ColorId = 2},
new Color { ColorName = "Grey", ColorCode = "GY", ColorId = 3},
new Color { ColorName = "Black", ColorCode = "BK", ColorId = 4},
new Color { ColorName = "Green", ColorCode = "GN", ColorId = 5},
new Color { ColorName = "Olive", ColorCode = "OL", ColorId = 6},
new Color { ColorName = "Orange", ColorCode = "O", ColorId = 7},
new Color { ColorName = "Pink", ColorCode = "PK", ColorId = 8},
new Color { ColorName = "Violet", ColorCode = "V", ColorId = 9},
new Color { ColorName = "Yellow", ColorCode = "YW", ColorId = 10}
}
.AsQueryable<Color>();
}
}
}
Models/Product.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace JQueryJsonSelectDemo.Models
{
public class Product
{
public string ProductName { get; set; }
public int ColorId { get; set; }
public int ProductId { get; set; }
public static IQueryable<Product> GetProductDataList()
{
return new List<Product>()
{
new Product { ProductName = "Cup", ColorId = 2, ProductId = 1},
new Product { ProductName = "MP3 Player", ColorId = 4, ProductId = 2},
new Product { ProductName = "52\" LCD TV", ColorId = 5, ProductId = 3},
new Product { ProductName = "Fork", ColorId = 6, ProductId = 4},
new Product { ProductName = "Spoon", ColorId = 10, ProductId = 5},
new Product { ProductName = "Shirt", ColorId = 6, ProductId = 6},
new Product { ProductName = "Pant", ColorId = 4, ProductId = 7},
new Product { ProductName = "Shoes", ColorId = 2, ProductId = 8},
new Product { ProductName = "Sun Glasses", ColorId = 1, ProductId = 9},
new Product { ProductName = "Pen", ColorId = 2, ProductId = 10}
}
.AsQueryable<Product>();
}
}
}
2-The Controller
Next, I created a class (IndexFormViewModel) to pass the Colors as a SelectList Collection to the strongly-typed view. And also create an Action FindProductsByColorID that returns a JsonResult that will be used by the JQuery code in the view to populate the cascading dropdown list.
Controllers/HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JQueryJsonSelectDemo.Models;
namespace JQueryJsonSelectDemo.Controllers
{
public class IndexFormViewModel
{
// Properties
public SelectList Colors { get; private set; }
// Constructor
public IndexFormViewModel()
{
var colors = from c in Color.GetColorDataList()
select c;
Colors = new SelectList(colors, "ColorId", "ColorName");
}
}
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "ASP.net MVC JQuery Cascading Select Demo!";
return View(new IndexFormViewModel());
}
public ActionResult About()
{
return View();
}
public JsonResult FindProductsByColorID(int colorid)
{
// Simulate Loading Data "wait"
System.Threading.Thread.Sleep(1500);
// return Json result using LINQ to SQL
return new JsonResult
{
Data = (from p in Product.GetProductDataList()
where p.ColorId == colorid
select p).ToArray<Product>()
};
}
}
}
3-Routing for the Ajax to call.
I create a route that I can call using the JQuery Ajax code.
Global.asax
routes.MapRoute(
"FindProducts",
"FindProducts/{colorid}",
new { controller = "Home", action = "FindProductsByColorID", colorid = "" }
);
4-The View
Finally, The view which contains the JQuery code to make an Ajax request to my Home Controller Action (FindProductsByColorID) which returns a Json Result. If data is returned from the Action, the Products dropdown will be removed from being disabled and the options will be populated by the array from the JsonResult.
Views/Home/Index.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<JQueryJsonSelectDemo.Controllers.IndexFormViewModel>" %>
<%@ Import Namespace="JQueryJsonSelectDemo.Models" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">Home Page</asp:Content>
<asp:Content ID="Head" ContentPlaceHolderID="HeadContent" runat="server">
<script type="text/javascript">
$(function() {
$("select#Colors").change(function() {
var color = $("#Colors > option:selected").attr("value");
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "FindProducts/" + color,
data: "{}",
dataType: "json",
success: function(data) {
$('#ProductsDiv > div').remove(); // remove any existing Products
if (data.length > 0) {
var options = '';
for (p in data) {
var product = data[p];
options += "<option value='" + product.ProductId + "'>" + product.ProductName + "</option>";
}
$("#Products").removeAttr('disabled').html(options);
} else {
$("#Products").attr('disabled', true).html('');
$("#ProductsDiv").append('<div>(None Found)</div>');
}
}
});
});
});
</script>
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
<label class="formlabel" for="Colors">Colors:</label>
<%=Html.DropDownList("Colors", Model.Colors)%>
</p>
<p>
<div id="ProductsDiv"></div>
</p>
<p>
<label class="formlabel" for="Products">Products:</label>
<select id="Products" disabled></select>
</p>
</asp:Content>
Recent Comments
femi wrote: Excellent! I wanted to implement something like th… [Read more]
Draven Group wrote: Thanks for informing this cool software. This soft… [Read more]
mbaird wrote: @John - Sorry, I do not. I program mainly in C#. [Read more]
John Marsing wrote: You don't perchance have a version of this in VB.N… [Read more]
my blogging net wrote: I want to have additional information using HTML, … [Read more]
Joedel wrote: Just one question, what are the other advantages o… [Read more]
Christian010 wrote: How interesting, thanks [Read more]
MICR Toner Tony wrote: This is a pretty interesting idea. Seems to be wor… [Read more]
Raman wrote: Hi Michael, I've playing with the code and ran … [Read more]
Franchises for sale wrote: It's interesting, the blog engine platform seems v… [Read more]