I am in the process of creating a 'Progress Report' with a list of questions and multiple choice answers. The questions are populated into the Progress Report automatically via a separate unrelated process in case it is relevant.
Code is as follows: Edit View:
@model App.Models.ProgressReport
@Html.EditorFor(model => model.ReportAnswers)
ReportAnswer.cshtml EditorTemplate (which shows the question and the answer from the Progress Report):
@model App.Models.ReportAnswer
<h3>
Question
</h3>
<p>
@Html.DisplayFor(x => x.Question.QuestionText)
</p>
<p>
@Html.EditorFor(x => x.Question.PossibleAnswers)
</p>
<p>
@Html.LabelFor(x => x.AnswerID)
@Html.TextBoxFor(x => x.AnswerID)
</p>
PossibleAnswer.cshtml (Editor Template which shows all available answers to the question):
@model App.Models.PossibleAnswer
<p>
@Html.DisplayFor(x => x.AnswerText)
@Html.RadioButtonFor(x => x.AnswerText, Model.AnswerID, new { Name =Model.QuestionID })
</p>
So this displays all associated questions from the Progress Report and the optional answers.
My problems:
1.) Is that each radio button has a different name which allows me to select all answers for a single question instead of unselecting one as the next is selected.
2.) The selected answer should load as selected the next time I edit the progress report. How to have one of the answers pre-selected on load based on the answer provided the last time the view was loaded.
3.) How to return the selected answer back to the Edit action in my ProgressReport Controller?
Thanks a bunch for any assistance
EditController Code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ReportID,ClientID,ReportDateSubmitted,ReportWeek")] ProgressReport progressReport)
{
if (ModelState.IsValid)
{
db.Entry(progressReport).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.ClientID = new SelectList(db.Clients, "ClientID", "ID", progressReport.ClientID);
return View(progressReport);
}
Your problem is the use of an
EditorTemplate
for typeofPossibleAnswer
. TheEditorFor()
method is designed to work with collections and add an prefixes and indexers to the property same so that it can be bound to a collection by theDefaultModelBinder
on post back. The second issue is that your binding the radio buttons to propertyAnswerText
ofPossibleAnswer
, when you should be binding toAnswerID
property ofReportAnswer
.Delete the
PossibleAnswer.cshtml
file and modify theReportAnswer.cshtml
toThis will generate html that looks like
Side note: NEVER attempt to override the
name
attribute (as in your usage ofnew { Name = Model.QuestionID }
. There is no surer way to guarantee model binding will fail :)