Radio buttons in editor template
I am creating a Progress Report with a list of multiple choice questions and answers. These questions are entered into the progress report automatically through a separate, unrelated process in case it matters.
The code looks like this: Edit View:
@model App.Models.ProgressReport @Html.EditorFor(model => model.ReportAnswers)
ReportAnswer.cshtml EditorTemplate (which shows the question and 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>
ChooseAnswer.cshtml (An editor template that shows all available answers to a 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 related questions from the progress report and additional answers.
My problems:
1.) Does each radio button have a different name that allows me to select all the answers for one question instead of deselecting it when I select the next.
2.) The selected answer should be loaded as selected the next time you edit the progress report. How to get one of the pre-selected on load responses based on the response when the view was last viewed.
3.) How do I return the selected response to the Edit action in my ProgressReport controller?
Thanks for any help
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);
}
source to share
Your problem is the use EditorTemplate
for typeof PossibleAnswer
. The method is EditorFor()
designed to work with collections and add prefixes and indexers to the property so that it can be bound to the collection using DefaultModelBinder
in the response message. The second problem is that binding the radio buttons to a property AnswerText
PossibleAnswer
is when you should bind to a property AnswerID
ReportAnswer
.
Delete the file PossibleAnswer.cshtml
and change ReportAnswer.cshtml
to
@model App.Models.ReportAnswer
<h3>Question</h3>
<p>@Html.DisplayFor(x => x.Question.QuestionText)</p>
@foreach(var answer in Model.Question.PossibleAnswers)
{
var id = string.Format("answer-{0}", answer.AnswerID);
<p>
@Html.RadioButtonFor(m => m.AnswerID, answer.AnswerID, new { id = id })
<label for="@id">@answer.AnswerText</label>
</p>
}
This will create html that looks like
<input type="radio" id="answer-1" name="[0].AnswerID" value="1" />
<label for="answer-1">Answer 1</label>
<input type="radio" id="answer-2" name="[0].AnswerID" value="2" />
<label for="answer-2">Answer 2</label>
Side note: NEVER tries to override an attribute name
(as in your use new { Name = Model.QuestionID }
. There is no reliable way to guarantee model binding :)
source to share