When using .net MVC RadioButtonFor(), how do you group so only one selection can be made?

前端 未结 3 1626
名媛妹妹
名媛妹妹 2020-11-28 09:52

This one has me stumped, I have a strongly typed view that has this loop to generate radiobuttons:

<% foreach (QuestionAnswer qa in Model.QuestionAnswers)         


        
3条回答
  •  無奈伤痛
    2020-11-28 10:17

    The first parameter of Html.RadioButtonFor() should be the property name you're using, and the second parameter should be the value of that specific radio button. Then they'll have the same name attribute value and the helper will select the given radio button when/if it matches the property value.

    Example:

    <%= Html.RadioButtonFor(m => m.Gender, "M" ) %> Male <%= Html.RadioButtonFor(m => m.Gender, "F" ) %> Female

    Here's a more specific example:

    I made a quick MVC project named "DeleteMeQuestion" (DeleteMe prefix so I know that I can remove it later after I forget about it).

    I made the following model:

    namespace DeleteMeQuestion.Models
    {
        public class QuizModel
        {
            public int ParentQuestionId { get; set; }
            public int QuestionId { get; set; }
            public string QuestionDisplayText { get; set; }
            public List 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; }
        }
    }
    

    There's a simple range validator in the model, just for fun. Next up, I made the following controller:

    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
                                                    {
                                                        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;
            }
        }
    }
    

    Finally, I made the following view that makes use of the model:

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
    
    
        Home Page
    
    
    
    
        <% using (Html.BeginForm()) { %>
    
            

    <%: Model.QuestionDisplayText %>

      <% foreach (var item in Model.Responses) { %>
    • <%= Html.RadioButtonFor(m => m.SelectedResponse, item.ResponseId, new {id="Response" + item.ResponseId}) %>
    • <% } %>
    <%= Html.ValidationMessageFor(m => m.SelectedResponse) %>
    <% } %>

    As I understand your context, you have questions with a list of available answers. Each answer will dictate the next question. Hopefully that makes sense from my model and TODO comments.

    This gives you the radio buttons with the same name attribute, but different ID attributes.

提交回复
热议问题