Reputation: 71
I am trying to convert a poorly developed C# web app to MVC2, and I am having difficulties trying to build a cascading dropdown. This is the code:
public IEnumerable<SelectListItem> SchoolList
{
get
{
DataTable dt = ClassModels.GetSchools();
List<SelectListItem> list = new List<SelectListItem>();
foreach (DataRow row in dt.Rows)
{
list.Add(new SelectListItem
{
Text = Convert.ToString(row["School"]),
Value = Convert.ToString(row["SID"]),
});
}
return list;
}
}
public IEnumerable<SelectListItem> DepartmentList
{
get
{
DataTable dt = DomData.GetDepartments(this is where the selected SID goes)
List<SelectListItem> list = new List<SelectListItem>();
foreach (DataRow row in dt.Rows)
{
list.Add(new SelectListItem
{
Text = Convert.ToString(row["Department"]),
Value = Convert.ToString(row["DID"]),
});
}
return list;
}
}
This is the model for the Departments
public static DataTable GetDepartments(int id)
{
string sql = string.Format(@"SELECT d.department, d.did
FROM dept d
WHERE d.did IN (SELECT DISTINCT(DID) FROM CDS WHERE SID = '{0}')
ORDER BY department", id);
DataTable db_table = new DataTable("departments");
SqlDataAdapter db_adapter = new SqlDataAdapter(sql, iau_conxn_string);
db_adapter.Fill(db_table);
//ddl_dep.DataSource = db_table;
//ddl_dep.DataValueField = "did";
//ddl_dep.DataTextField = "department";
//ddl_dep.DataBind();
return db_table;
}
Sadly, I have to do this without AJAX or jQuery.
Upvotes: 2
Views: 2715
Reputation: 1039278
Since you cannot use AJAX but only pure javascript you could subscribe to the onchange event of the first dropdown and then submit the form in order to populate the second dropdown.
But before putting this into action let's start by defining a view model. In my example I will obviously remove all the noise that was present in your question (things like DataTables and data access specific code and simply hardcode the values so that the answer be more general, so simply replace those hardcoded values with a call to your data access method):
public class MyViewModel
{
public MyViewModel()
{
Departments = Enumerable.Empty<SelectListItem>();
}
public int? SchoolId { get; set; }
public IEnumerable<SelectListItem> SchoolList
{
get
{
// TODO: fetch the schools from a DB or something
return new[]
{
new SelectListItem { Value = "1", Text = "school 1" },
new SelectListItem { Value = "2", Text = "school 2" },
};
}
}
public int? DepartmentId { get; set; }
public IEnumerable<SelectListItem> Departments { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Departments(MyViewModel model)
{
// TODO: use model.SchoolId to fetch the corresponding departments
// from your database or something
model.Departments = new[]
{
new SelectListItem { Value = "1", Text = "department 1 for school id " + model.SchoolId },
new SelectListItem { Value = "2", Text = "department 2 for school id " + model.SchoolId },
new SelectListItem { Value = "3", Text = "department 3 for school id " + model.SchoolId },
};
return View("Index", model);
}
}
and finally a view:
<%@ Page
Language="C#"
Inherits="System.Web.Mvc.ViewPage<MyViewModel>"
%>
<% using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myform", data_departments_url = Url.Action("Departments") })) { %>
<div>
<%= Html.LabelFor(x => x.SchoolId) %>
<%= Html.DropDownListFor(
x => x.SchoolId,
Model.SchoolList,
"-- School --",
new { id = "school" }
) %>
</div>
<div>
<%= Html.LabelFor(x => x.DepartmentId) %>
<%= Html.DropDownListFor(
x => x.DepartmentId,
Model.Departments,
"-- Department --"
) %>
</div>
<% } %>
and the last bit is of course javascript to subscribe to the onchange event of the first dropdown and submit the form to the server in order to populate the second dropdown:
window.onload = function () {
document.getElementById('school').onchange = function () {
if (this.value) {
var form = document.getElementById('myform');
form.action = form.getAttribute('data-departments-url');
form.submit();
}
};
};
And for those that don't have the same constraints as you and can use AJAX and jQuery take a look at the following answer: https://stackoverflow.com/a/4459084/29407
Upvotes: 1