ASP.NET MVC Да / Нет Радиокнопки с сильно связанной моделью MVC

132

Кто-нибудь знает, как привязать переключатель «Да / Нет» к логическому свойству строго типизированной модели в ASP.NET MVC.

Модель

public class MyClass
{
     public bool Blah { get; set; }
}

Посмотреть

<%@  Page Title="blah"  Inherits="MyClass"%>
    <dd>
        <%= Html.RadioButton("blah", Model.blah) %> Yes
        <%= Html.RadioButton("blah", Model.blah) %> No
    </dd>

Спасибо

РЕШЕНИЕ:

Спасибо Брайану за направление, но это было противоположно тому, что он написал. Как так -

<%@  Page Title="blah"  Inherits="MyClass"%>
<dd>
    <%= Html.RadioButton("blah", !Model.blah) %> Yes
    <%= Html.RadioButton("blah", Model.blah) %> No
</dd>
brianstewey
источник
4
«Проблема» с этими решениями (и я использую стиль Бен Кулл в своем проекте) заключается в том, что вы не можете делать с ними ярлыки. Оба входа радиокнопки будут иметь одинаковый идентификатор и имя, поэтому, если вы используете Html.LabelFor, он будет связываться с первым входом радиокнопки в DOM с этим идентификатором. Как я уже сказал, я использую это решение для переключателей для представления логического поля, я просто хотел, чтобы люди знали, что ярлыки будут немного шаткими.
Gromer
2
Посмотрите ответ Джеффа Бобиша, чтобы увидеть, как элегантно решить проблему с этикеткой.
Рене

Ответы:

74

Выбран второй параметр, поэтому используйте! выбрать значение нет, когда логическое значение ложно.

<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 
Брайан Майнс
источник
198

Если вы используете MVC 3 и Razor, вы также можете использовать следующее:

@Html.RadioButtonFor(model => model.blah, true) Yes
@Html.RadioButtonFor(model => model.blah, false) No
Бен Калл
источник
56

Вот более полный пример, в котором используется fieldsetдля удобства и первая кнопка указана по умолчанию. Без того fieldset, для чего переключатели в целом не могут быть определены программно.

Модель

public class MyModel
{
    public bool IsMarried { get; set; }
}

Посмотреть

<fieldset>
    <legend>Married</legend>

    @Html.RadioButtonFor(e => e.IsMarried, true, new { id = "married-true" })
    @Html.Label("married-true", "Yes")

    @Html.RadioButtonFor(e => e.IsMarried, false, new { id = "married-false" })
    @Html.Label("married-false", "No")
</fieldset>

Вы можете добавить @checkedаргумент к анонимному объекту, чтобы установить переключатель по умолчанию:

new { id = "married-true", @checked = 'checked' }

Обратите внимание, что вы можете связать строку, заменив trueи falseстроковыми значениями.

Даниэль Иммс
источник
На самом деле вы должны использовать new {id = Html.Id ("замуж-истина))}, уменьшая потенциальные проблемы области видимости генерируемых префиксов идентификаторов.
eoleary
26

Немного основываясь на ответе Бена, я добавил атрибуты для идентификатора, чтобы использовать метки.

<%: Html.Label("isBlahYes", "Yes")%><%= Html.RadioButtonFor(model => model.blah, true, new { @id = "isBlahYes" })%>
<%: Html.Label("isBlahNo", "No")%><%= Html.RadioButtonFor(model => model.blah, false, new { @id = "isBlahNo" })%>

Надеюсь, это поможет.

CTC
источник
7
Обычно метка стоит после переключателя.
Даниэль Иммс
6
Поместить ярлык вокруг радиокнопки вполне допустимо.
Скотт Бейкер
23

Добавление тегов меток вокруг радиокнопок с использованием обычного HTML также устранит проблему с 'labelfor':

<label><%= Html.RadioButton("blah", !Model.blah) %> Yes</label>
<label><%= Html.RadioButton("blah", Model.blah) %> No</label>

При нажатии на текст теперь выбирается соответствующий переключатель.

Джефф Бобиш
источник
8

или MVC 2.0:

<%= Html.RadioButtonFor(model => model.blah, true) %> Yes
<%= Html.RadioButtonFor(model => model.blah, false) %> No
Стаффорд Уильямс
источник
5

Если я могу бросить свою шляпу в кольцо, я думаю, что есть более чистый способ, чем существующие ответы, чтобы повторно использовать функциональность переключателя.

Допустим, у вас есть следующее свойство в вашей ViewModel :

Public Class ViewModel
    <Display(Name:="Do you like Cats?")>
    Public Property LikesCats As Boolean
End Class

Вы можете выставить это свойство через повторно используемый шаблон редактора :

Сначала создайте файл Views/Shared/EditorTemplates/YesNoRadio.vbhtml

Затем добавьте следующий код в YesNoRadio.vbhtml :

@ModelType Boolean?

<fieldset>
    <legend>
        @Html.LabelFor(Function(model) model)
    </legend>

    <label>
        @Html.RadioButtonFor(Function(model) model, True) Yes
    </label>
    <label>
        @Html.RadioButtonFor(Function(model) model, False) No
    </label>
</fieldset>

Вы можете вызвать редактор для свойства, вручную указав имя шаблона в вашем представлении :

@Html.EditorFor(Function(model) model.LikesCats, "YesNoRadio")

Плюсы:

  • Получите возможность писать HTML в редакторе HTML вместо добавления строк в код.
  • Сохраняет аннотацию DataName
  • Позволяет щелчкам на ярлыке переключать переключатель
  • Наименьший возможный код для поддержки в форме (1 строка). Если что-то не так с тем, как он разрывается, исправьте это с помощью шаблона.
KyleMit
источник
Это хорошо, но как насчет третьего варианта для логического? @ Html.RadioButtonFor (функция (модель) Model.IsVerified, True) <span> Да </ span> @ Html.RadioButtonFor (функция (модель) Model.IsVerified, False) <span> Нет </ span> @ Html.RadioButtonFor (Функция (модель) Model.IsVerified, Nothing)) <span> В ожидании </ span>
JoshYates1980
1

Я закончил упаковывать это в метод расширения, чтобы (1) я мог генерировать метку и радио сразу и (2) чтобы мне не пришлось возиться с указанием моих собственных идентификаторов:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString RadioButtonAndLabelFor<TModel, TProperty>(this HtmlHelper<TModel> self, Expression<Func<TModel, TProperty>> expression, bool value, string labelText)
    {
        // Retrieve the qualified model identifier
        string name = ExpressionHelper.GetExpressionText(expression);
        string fullName = self.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        // Generate the base ID
        TagBuilder tagBuilder = new TagBuilder("input");
        tagBuilder.GenerateId(fullName);
        string idAttr = tagBuilder.Attributes["id"];

        // Create an ID specific to the boolean direction
        idAttr = String.Format("{0}_{1}", idAttr, value);

        // Create the individual HTML elements, using the generated ID
        MvcHtmlString radioButton = self.RadioButtonFor(expression, value, new { id = idAttr });
        MvcHtmlString label = self.Label(idAttr, labelText);

        return new MvcHtmlString(radioButton.ToHtmlString() + label.ToHtmlString());
    }
}

Использование:

@Html.RadioButtonAndLabelFor(m => m.IsMarried, true, "Yes, I am married")
атака
источник