これには困惑しています。ラジオボタンを生成するためのこのループを持つ、厳密に型指定されたビューがあります。
<% foreach (QuestionAnswer qa in Model.QuestionAnswers)
{ %>
<%= Html.RadioButtonFor(model => model.QuestionAnswers[(int)qa.QuestionID - 1].AnswerValue, "Checked" ) %>
<%= Html.Encode(qa.OptionValue) %>
<% } %>
レンダリングは正常に行われますが、名前が同じではないため、複数のラジオボタンを選択できます。ラジオボタンを 1 つだけ選択できるようにグループ化するにはどうすればよいでしょうか。
ご協力いただければ幸いです。
ベストアンサー1
Html.RadioButtonFor() の最初のパラメータは、使用しているプロパティ名にし、2 番目のパラメータは、その特定のラジオ ボタンの値にする必要があります。そうすると、それらは同じ名前属性値を持ち、ヘルパーは、プロパティ値と一致する場合に、指定されたラジオ ボタンを選択します。
例:
<div class="editor-field">
<%= Html.RadioButtonFor(m => m.Gender, "M" ) %> Male
<%= Html.RadioButtonFor(m => m.Gender, "F" ) %> Female
</div>
より具体的な例を以下に示します。
私は「DeleteMeQuestion」という名前の簡単な MVC プロジェクトを作成しました (DeleteMe プレフィックスを付けると、後で忘れたときに削除できるようになります)。
次のようなモデルを作成しました。
namespace DeleteMeQuestion.Models
{
public class QuizModel
{
public int ParentQuestionId { get; set; }
public int QuestionId { get; set; }
public string QuestionDisplayText { get; set; }
public List<Response> Responses { get; set; }
[Range(1,999, ErrorMessage = "Please choose a response.")]
public int SelectedResponse { get; set; }
}
public class Response
{
public int ResponseId { get; set; }
public int ChildQuestionId { get; set; }
public string ResponseDisplayText { get; set; }
}
}
モデルには、楽しみのために、単純な範囲検証機能があります。次に、次のコントローラーを作成しました。
namespace DeleteMeQuestion.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index(int? id)
{
// TODO: get question to show based on method parameter
var model = GetModel(id);
return View(model);
}
[HttpPost]
public ActionResult Index(int? id, QuizModel model)
{
if (!ModelState.IsValid)
{
var freshModel = GetModel(id);
return View(freshModel);
}
// TODO: save selected answer in database
// TODO: get next question based on selected answer (hard coded to 999 for now)
var nextQuestionId = 999;
return RedirectToAction("Index", "Home", new {id = nextQuestionId});
}
private QuizModel GetModel(int? questionId)
{
// just a stub, in lieu of a database
var model = new QuizModel
{
QuestionDisplayText = questionId.HasValue ? "And so on..." : "What is your favorite color?",
QuestionId = 1,
Responses = new List<Response>
{
new Response
{
ChildQuestionId = 2,
ResponseId = 1,
ResponseDisplayText = "Red"
},
new Response
{
ChildQuestionId = 3,
ResponseId = 2,
ResponseDisplayText = "Blue"
},
new Response
{
ChildQuestionId = 4,
ResponseId = 3,
ResponseDisplayText = "Green"
},
}
};
return model;
}
}
}
最後に、モデルを活用した次のビューを作成しました。
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<DeleteMeQuestion.Models.QuizModel>" %>
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) { %>
<div>
<h1><%: Model.QuestionDisplayText %></h1>
<div>
<ul>
<% foreach (var item in Model.Responses) { %>
<li>
<%= Html.RadioButtonFor(m => m.SelectedResponse, item.ResponseId, new {id="Response" + item.ResponseId}) %>
<label for="Response<%: item.ResponseId %>"><%: item.ResponseDisplayText %></label>
</li>
<% } %>
</ul>
<%= Html.ValidationMessageFor(m => m.SelectedResponse) %>
</div>
<input type="submit" value="Submit" />
<% } %>
</asp:Content>
あなたの状況を理解すると、利用可能な回答のリストがある質問があります。それぞれの回答によって次の質問が決まります。私のモデルと TODO コメントからそれが理解できるといいのですが。
これにより、名前属性は同じだが ID 属性が異なるラジオ ボタンが作成されます。