При использовании .net MVC RadioButtonFor (), как вы группируете, чтобы можно было сделать только один выбор? - PullRequest
62 голосов
/ 25 июня 2010

Это меня озадачило, у меня строго типизированное представление, которое имеет этот цикл для генерации радиокнопок:

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

Отрисовывается нормально, но поскольку имена не совпадают, вы можете выбрать более 1 радиокнопки. Как их сгруппировать, чтобы можно было выбрать только 1 радиокнопку?

Любая помощь будет оценена!

Ответы [ 3 ]

118 голосов
/ 26 июня 2010

Первый параметр Html.RadioButtonFor () должен быть именем свойства, которое вы используете, а второй параметр должен быть значением этой конкретной радиокнопки. Тогда они будут иметь одно и то же значение атрибута имени, и помощник выберет данную радио-кнопку, если / если она соответствует значению свойства.

Пример:

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

Вот более конкретный пример:

Я сделал быстрый проект MVC с именем «DeleteMeQuestion» (префикс 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.

Это дает вам переключатели с тем же атрибутом имени, но с разными атрибутами идентификатора.

5 голосов
/ 29 января 2015

В моем случае у меня была коллекция переключателей, которые должны были быть в группе. Я просто включил свойство «Выбранные» в модель. Затем в цикле для вывода радиокнопок просто выполните ...

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

Таким образом, имя одинаково для всех переключателей. Когда форма публикуется, свойство «Выбрано» равно заголовку категории (или идентификатору или какому-либо другому), и это может быть использовано для обновления привязки на соответствующей кнопке радио, как это ...

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

Возможно, это не лучший способ, но он работает.

0 голосов
/ 14 марта 2012

В тех случаях, когда атрибут имени отличается, проще всего управлять радиогруппой через JQuery. Когда опция выбрана, используйте JQuery, чтобы отменить выбор других опций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...