I have 2 dropdownlists, the second (department) cascades from the first (division).
I use a jquery script to update the second drop down list.
When the user clicks submit, the underlying model is updated, apart from the new value for department.
2 ideas I have for fixing this are;
a) Generate a postback. Prefer not to do this because of bad user experience.
b) With a JQuery change event, make a call to server side and set a ViewData variable that I can use to update the field in the model later.
However there must be a better way.
This is the view;
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/AdminAccounts.master"
Inherits="System.Web.Mvc.ViewPage<SHP.WebUI.Models.EmployeeViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Add
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="AdminAccountsContent" runat="server">
<% using (Html.BeginForm("Add", "Employee")) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Add Employee</legend>
<table>
<tr>
<td align="right">
<%: Html.LabelFor(model => model.Employee.UserName)%>
</td>
<td>
<%: Html.EditorFor(model => model.Employee.UserName)%>
<%: Html.ValidationMessageFor(model => model.Employee.UserName)%>
</td>
</tr>
<tr>
<td align="right">
<%: Html.LabelFor(model => model.Division.DivisionId) %>
</td>
<td>
<%: Html.DropDownListFor(model => model.Division.DivisionId, Model.DivisionSelectList, "<--Select-->")%>
<%: Html.ValidationMessageFor(model => model.Division.DivisionId)%>
</td>
</tr>
<tr>
<td align="right">
<%: Html.LabelFor(model => model.Department.DepartmentId) %>
</td>
<td>
<%: Html.DropDownListFor(model => model.Department.DepartmentId, Model.DepartmentSelectList, "<--Select-->")%>
<%: Html.ValidationMessageFor(model => model.Department.DepartmentId) %>
</td>
</tr>
<tr>
<td align="center" colspan="2" style="padding-top:20px;">
<input type="submit" value="Save" /></td>
</tr>
</table>
<% if (ViewData["LastPerson"].ToString().Length > 0)
{ %>
<p>
At time <% Response.Write(DateTime.Now.ToString("T")); %>
- You have just entered <%Response.Write(ViewData["LastPerson"].ToString()); %>.
</p>
<%} %>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
<script language="javascript" type="text/javascript">
//Hook onto the DivisionId list's onchange event
$("#Division_DivisionId").change(function () {
//build the request url
var url = '<%: Url.Content("~/")%>' + "Employee/GetDepartments";
//fire off the request, passing it the id which is the DivisionId's selected item value
$.getJSON(url, { divisionId: $("#Division_DivisionId").val() }, function (data) {
//Clear the Department list
$("#Department_DepartmentId").empty();
$("#Department_DepartmentId").append("<option><--Select--></option>");
//Foreach Department in the list, add a department option from the data returned
$.each(data, function (index, optionData) {
$("#Department_DepartmentId").append(
"<option value='" + optionData.DepartmentId + "'>" +
optionData.DepartmentName + "</option>");
});
});
}).change();
</script>
I’d make a partial view that generates the second drop down. That would look something like this:
It’s the
Inheritsattribute that make it strongly typed, your page above is also strongly typed.While you are at it, change this code:
into:
Next, to add a change event to the division drop down change this line of code:
into:
And now, let’s add the
divisionChanged()javascript function. It would look something like this:That function makes an ajax post to your GetDepartmentDropDown action and takes the returned html and replaces the department drop down with it.
Your GetDepartmentDropDown will have to take whatever data you need to recreate the
EmloyeeViewModelyou passed in the view in the first place, (this data should be included in thedataproperty in the ajax call in the javascript function) and then return something like this:You shouldn’t initialize the model in the return statement of course, it’s just there to give an idea of what needs to be done.
That should do it I think. Then when you post the form the receiving action should be able to pick up the value.
Hope it helps.