Reputation: 93
I am loading a partial view depeding on dropdownlist selection just like how it is described here: Load partial view depending on dropdown selection in MVC3. My code looks like this:
View:
@....ParentModel
@using (Html.BeginForm("Method", "Controller", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div id="info">
<div id="info-selection">
@Html.LabelFor(m => m.SavedInfo)
@Html.DropDownListFor(m => m.SavedInfo , infoListItems, new { @id = "info-dropdown" })
</div>
<div id="info-describtion">
@Html.EditorFor(m => m.ChildModel)
</div>
</div>
<input type="submit" id="confirm_btn" value="Go!" />
}
<script>
$('#info-dropdown').change(function () {
var id = $(this).val();
$.get('/Cart/SelectInfo/' + id, function (data) {
$('#info-describtion').html(data);
//$('#info-describtion').fadeIn('fast');
});
});
</script>
PartialView:
@model ...Info
@{
List<SelectListItem> listMetroItems = new List<SelectListItem>();
listMetroItems.Add(new SelectListItem
{
Text = "no metro",
Value = "NoMetroAvailable",
Selected = true
});
}
<ul id="info-left">
<li>
@Html.LabelFor(m => m.Undegraund)
@Html.DropDownListFor(m => m.Undegraund, listMetroItems)
</li>
<li>
@Html.LabelFor(m => m.House)
@Html.TextBoxFor(m => m.House)
</li>
<li>
@Html.LabelFor(m => m.Flat)
@Html.TextBoxFor(m => m.Flat)
</li>
<li>
@Html.LabelFor(m => m.Floor)
@Html.TextBoxFor(m => m.Floor)
</li>
</ul>
<ul id="info-right">
<li>
@Html.LabelFor(m => m.Street)
@Html.TextBoxFor(m => m.Street)
</li>
<li>
@Html.LabelFor(m => m.Building)
@Html.TextBoxFor(m => m.Building)
</li>
<li>
@Html.LabelFor(m => m.Porch)
@Html.TextBoxFor(m => m.Porch)
</li>
<li>
@Html.LabelFor(m => m.IntercomCode)
@Html.TextBoxFor(m => m.IntercomCode)
</li>
</ul>
Controller:
public ActionResult SelectInfo(int id)
{
Info partialViewModel = new Info(id);
return PartialView("~/Views/Shared/EditorTemplates/InfoModel.cshtml", partialViewModel);
}
One thing I can't get to work properly: the partial view I load as you can see is the part of the form. The form content updates on dropdown change perfectly. But when I click the submit button of the form it posts the obsolete data not the one replaced with SelectInfo() method! I think its due to the fact that the ParentModel of the whole view doesnt get updated when partial view updates. What are the choices to resolve this?
Upvotes: 1
Views: 786
Reputation: 2052
This is what I believe is happening. First, before selecting any drop down, load your page and view the source. Note the Name property of your different inputs. They will be something like
<input class="text-box single-line" id="Info_House" name="Info.House" type="text" value="">
Note the name. Info.House. The name is what drives model binding in MVC ASP.net. Now note that your partial view takes an Info model directly. Not a parent model. So once you select a drop down item and your partial view populates you now have inputs like so :
<input id="House" name="House" type="text" value="House">
Now note the new name. The html produced is attempting to bind DIRECTLY to a property called "House". So it assumes your model has something like Model.House. But your Parent model does not. It has Model.Info.House
So what you need to do is the following. In your controller
Controller
public ActionResult SelectInfo(int id)
{
Info info = new Info(id);
var parentModel = new ParentModel { Info = info};
return PartialView("~/Views/Shared/EditorTemplates/InfoModel.cshtml", parentModel);
}
Now in your partial view you would have
Partial View (note the partial view now takes the ParentModel. Not the child model.
@model MvcApplication1.Models.ParentModel
@{
List<SelectListItem> listMetroItems = new List<SelectListItem>();
listMetroItems.Add(new SelectListItem
{
Text = "no metro",
Value = "NoMetroAvailable",
Selected = true
});
}
<ul id="info-left">
<li>
@Html.LabelFor(m => m.Info.Undergraund)
@Html.DropDownListFor(m => m.Info.Undergraund, listMetroItems)
</li>
<li>
@Html.LabelFor(m => m.Info.House)
@Html.TextBoxFor(m => m.Info.House)
</li>
<li>
@Html.LabelFor(m => m.Info.Flat)
@Html.TextBoxFor(m => m.Info.Flat)
</li>
<li>
@Html.LabelFor(m => m.Info.Floor)
@Html.TextBoxFor(m => m.Info.Floor)
</li>
</ul>
<ul id="info-right">
<li>
@Html.LabelFor(m => m.Info.Street)
@Html.TextBoxFor(m => m.Info.Street)
</li>
<li>
@Html.LabelFor(m => m.Info.Building)
@Html.TextBoxFor(m => m.Info.Building)
</li>
<li>
@Html.LabelFor(m => m.Info.Porch)
@Html.TextBoxFor(m => m.Info.Porch)
</li>
<li>
@Html.LabelFor(m => m.Info.IntercomCode)
@Html.TextBoxFor(m => m.Info.IntercomCode)
</li>
</ul>
Upvotes: 1