I’m new with MVC3 framework. So I was practicing and trying to learn how to have a Cascading dropdownlist using jquery. And I found this sample by Rick Anderson: http://blogs.msdn.com/b/rickandy/archive/2012/01/09/cascasding-dropdownlist-in-asp-net-mvc.aspx
So I tried to customize my own website with this sample in order to have a cascading dropdownlist. Here is my controller:
private SelectList GetMakeSelectList()
{
var makeQry = from m in db.Car
orderby m.Make
select m.Make;
return new SelectList(makeQry.ToArray(), "Make");
}
public ActionResult MakeList()
{
if (HttpContext.Request.IsAjaxRequest())
return Json(GetMakeSelectList(), JsonRequestBehavior.AllowGet);
return RedirectToAction("Categories");
}
public ActionResult ModelList(string Make)
{
string make = Make;
var model = from s in db.Car
where s.Make == make
select s.Model;
if (HttpContext.Request.IsAjaxRequest())
return Json(new SelectList(
model.ToArray())
, JsonRequestBehavior.AllowGet);
return RedirectToAction("Categories");
}
public ActionResult Categories()
{
return View();
}
and here is my model:
public class Car
{
public int ID { get; set; }
public String Make { get; set; }
public String Model { get; set; }
public decimal Price { get; set; }
public String Edition { get; set; }
public String Type { get; set; }
public decimal Consumption { get; set; }
public decimal Acceleration { get; set; }
public decimal Horsepower { get; set; }
public bool? Convertible { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet<Car> Car { get; set; }
}
The problem is: String Make in ModelList method is null.
So I’m trying to not set my values manually in model class but set them just in the database.
My guess is: that the SelectList(makeQry.ToArray(), “Make”), the selected value’s type that I’m using is not what it expects to be. But I have no idea how to pass the expected type for a query.
And I’m using Jquery for this.
I would really appreciate any help.
Update:
Here is the View:
@model IEnumerable<Cars.Models.Car>
<script src="@Url.Content("~/Scripts/GetMake.js")"></script>
<script src="@Url.Content("~/Scripts/makeModel.js")"></script>
<link rel="stylesheet" type="text/css" href="@Url.Content("~/Content/CategoriesStyle.css")" />
@using (Html.BeginForm("Categories", "Category", FormMethod.Post,
new { id = "CategoryFormID",
data_modelListAction = @Url.Action("ModelList"),
data_makeListAction = @Url.Action("MakeList")})) {
<div id="content">
<fieldset>
<legend>Advanced Search</legend>
<div class="myform">
<p>Search the car you're looking for in all details you can imagine right here!</p>
<div id="MakeDivID">
<label>Make</label>
<select id="MakeID" name="Make"></select>
</div>
<div id="ModelDivID">
<label>Model</label>
<select id="ModelID" name="Model"></select>
</div>
<button type="submit" id="SubmitID">Search</button>
</div>
</fieldset>
</div>
}
and this would be my Jquery where I fill the dropboxes and call the methods:
this is GetMake.js
$(function () {
var URL = $('#CategoryFormID').data('makeListAction');
$.getJSON(URL, function (data) {
var items = "<option>Select a Car Make</option>";
$.each(data, function (i, make) {
if (make.Text.indexOf("\'") > -1) {
s = make.Text;
alert(s + ": Country.Value cannot contain \'")
}
items += "<option>" + make.Text + "</option>";
});
$('#MakeID').html(items);
});
});
and this is makeModel.js:
$(function () {
$('#ModelDivID').hide();
$('#SubmitID').hide();
$('#MakeID').change(function () {
var URL = $('#CategoryFormID').data('modelListAction');
$.getJSON(URL + '/' + $('#MakeID').val(), function (data) {
var items = '<option>Select a Model</option>';
$.each(data, function (i, model) {
items += "<option>" + model.Text + "</option>";
// state.Value cannot contain ' character. We are OK because state.Value = cnt++;
});
$('#ModelID').html(items);
$('#ModelDivID').show();
});
});
$('#ModelID').change(function () {
$('#SubmitID').show();
});
});
Second Update:
I forgot the mention the result that I get which is not what I’m looking for.
The result is that the first dropbox appears with all the correct values inside, when I click one of them, the second dropbox appears but it’s empty since I’m not passing the Make object is null in ModelList().
Third Update:
here is my routing as you asked. I hope this is what you were looking for.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Cars
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// Use LocalDB for Entity Framework by default
Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
}
Having seen your routes, I think this is your issue:
Your routes say that the parameter must be called
id, so that it can be mapped (this is the default routing.. which is why I wanted to double check).To fix your issue, you probably only need to change the ModelList function to be this: