代码之家  ›  专栏  ›  技术社区  ›  Mark Kadlec

使用.net MVC RadioButtonFor()时,如何分组以便只能进行一个选择?

  •  62
  • Mark Kadlec  · 技术社区  · 14 年前

    这个让我很困惑,我有一个强类型视图,它有一个循环来生成单选按钮:

    <% foreach (QuestionAnswer qa in Model.QuestionAnswers)
       { %>
        <%= Html.RadioButtonFor(model => model.QuestionAnswers[(int)qa.QuestionID - 1].AnswerValue, "Checked" ) %>
        <%= Html.Encode(qa.OptionValue) %>
    <% } %>
    

    它呈现良好,但由于名称不同,您可以选择多个单选按钮。如何将它们分组以便只能选择一个单选按钮?

    任何帮助都将不胜感激!

    3 回复  |  直到 12 年前
        1
  •  128
  •   a7drew    14 年前

    RadioButtonFor()的第一个参数应该是您正在使用的属性名,第二个参数应该是特定单选按钮的值。然后它们将具有相同的name属性值,并且当/如果与属性值匹配时,助手将选择给定的单选按钮。

    例子:

    <div class="editor-field">
        <%= Html.RadioButtonFor(m => m.Gender, "M" ) %> Male
        <%= Html.RadioButtonFor(m => m.Gender, "F" ) %> Female
    </div>
    

    我做了一个名为“DeleteMeQuestion”(deleteMePrefix)的快速MVC项目,这样我知道我可以在忘记它之后删除它。

    我做了以下模型:

    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属性的单选按钮。

        2
  •  7
  •   simonpkerr    9 年前

    在我的例子中,我有一个单选按钮的集合,需要在一个组中。

    @Html.RadioButtonFor(m => Model.Selected, Model.Categories[i].Title)
    

    这样,所有单选按钮的名称都相同。当表单发布时,“Selected”属性等于类别标题(或id或其他任何内容),这可用于更新相关单选按钮上的绑定,如下所示。。。

    model.Categories.Find(m => m.Title.Equals(model.Selected)).Selected = true;
    

    也许不是最好的方法,但确实有效。

        3
  •  -6
  •   Bob    12 年前

    在name属性不同的情况下,最容易通过JQuery控制无线组。选择一个选项后,使用JQuery取消选择其他选项。