My question is two-fold.
I have a View that gets data on the change of a drop down selection.
The data retrieved is a List property of a ViewModel class using an Ajax call.
This data is shown as a selection of check boxes for the user to select any number of them.
If I return a Partial View from an AJAX call, this is easy enough, but from what I have experienced, this doesn't work for POST'ing back to the controller. Nothing is bound correctly.
From what I have read the correct way is to use EditorFor, So firstly, I cannot figure out how to populate the EditorFor from the AJAX call.
Secondly, If I test by sending initial data from my GET, the EditorFor displays the correct checkbox options, but when I POST, the count of the items is 0.
View:
@model EngineeringAssistantMVC.Controllers.FirmwareController.FirmwareViewModel
@using (Html.BeginForm("Upload", "Firmware", FormMethod.Post, new { @id = "uploadFirmwareForm", @class = "form-horizontal" }))
{
<!-- Device -->
<div class="form-group">
<div class="col-lg-1">
@Html.LabelFor(x => x.Device, htmlAttributes: new { @class = "control-label" })
</div>
<div class="col-lg-2">
@Html.DropDownListFor(x => x.Device, ViewBag.Devices as IEnumerable<SelectListItem>, new { @class = "form-control", @id = "Devices" })
</div>
<div class="col-lg-9">
@Html.ValidationMessageFor(x => x.Device, "", new { @class = "text-danger" })
</div>
</div>
@Html.EditorFor(x => x.SelectedModels, "SelectedModels", new { @id = "Models" })
@Html.HiddenFor(x => x.SelectedModels)
}
And the AJAX call:
function GetModels() {
$.ajax({
type: "GET",
url: '@Url.Action("GetModels", "Firmware", null)',
data: { SelectedDevice: $('#Devices').val() },
success: function (dataSet) {
//$('#Models').html(dataSet);
//$('#Models').data(dataSet);
//$('#Models').val(dataSet);
// How do I populate the EditorFor from the dataSet returned?
},
error: function (err) {
console.log("ERROR: " + err.responseText);
},
})
}
SelectedModels EditFor Template:
@model IEnumerable<EngineeringAssistantMVC.ViewModels.ModelViewModel>
@foreach (var item in Model)
{
@Html.CheckBoxFor(x => item.IsSelected)
@Html.Label(item.Description)
@Html.HiddenFor(x => item.ModelId)
@Html.HiddenFor(x => item.IsSelected)
@Html.HiddenFor(x => item.Description)
}
Controller:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase uploadFile, FirmwareViewModel firmwareViewModel)
{
// firmwareViewModel.SelectedModels count is 0 here
}
ModelFirmware Class:
public class ModelFirmware
{
public int ModelFirmwareId { get; set; }
public int FirmwareId { get; set; }
public int ModelId { get; set; }
}
FirmwareViewModel:
public class FirmwareViewModel
{
public int FirmwareViewModelId { get; set; }
[Required]
public string Device { get; set; }
public ICollection<ModelViewModel> SelectedModels { get; set; }
}
I just can't get it to work correctly.
EDIT 1: - Add method that returns the models
[HttpGet]
public ActionResult GetModels(string SelectedDevice)
{
var deviceAbbreviation = _dbContext.Radios.Where(x => x.RadioName == SelectedDevice).Select(x => x.ProjectAbbreviation).FirstOrDefault();
var models = _dbContext.AnatomyModels.Where(x => x.SerialPrefix.StartsWith(deviceAbbreviation.Trim()) && x.ParentId == 0).ToList();
List<ModelViewModel> mvms = models.Select(x => new ModelViewModel()
{
ModelId = x.AnatomyModelId,
Description = x.SerialPrefix,
IsSelected = false,
}).ToList();
return Json(mvms);
}