Botões de opção ASP.NET MVC Sim / Não com modelo fortemente vinculado MVC

132

Alguém sabe como vincular um botão de opção Sim / Não a uma propriedade booleana de um Modelo fortemente tipado no ASP.NET MVC.

Modelo

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

Visão

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

obrigado

SOLUÇÃO:

Obrigado por Brian pela direção, mas foi o oposto do que ele escreveu. Como assim -

<%@  Page Title="blah"  Inherits="MyClass"%>
<dd>
    <%= Html.RadioButton("blah", !Model.blah) %> Yes
    <%= Html.RadioButton("blah", Model.blah) %> No
</dd>
brianstewey
fonte
4
O "problema" com essas soluções (e estou usando o estilo Ben Cull no meu projeto) é que você não pode fazer etiquetas com elas. As duas entradas do botão de opção terão o mesmo ID e nome; portanto, se você usar Html.LabelFor, ele será vinculado à primeira entrada do botão de opção no DOM com esse ID. Como eu disse, estou usando essas soluções para botões de opção para representar um campo booleano, só queria que as pessoas soubessem que os rótulos serão um pouco complicados.
Gromer
2
Veja a resposta de Jeff Bobish para ver como corrigir o problema do rótulo de maneira elegante.
René

Respostas:

74

O segundo parâmetro está selecionado, então use o! para selecionar o valor no quando o booleano for falso.

<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 
Brian Mains
fonte
198

Se você estiver usando o MVC 3 e o Razor, também poderá usar o seguinte:

@Html.RadioButtonFor(model => model.blah, true) Yes
@Html.RadioButtonFor(model => model.blah, false) No
Ben Cull
fonte
56

Aqui está um exemplo mais completo usando a fieldsetpor razões de acessibilidade e especificando o primeiro botão como padrão. Sem a fieldset, para que servem os botões de opção como um todo, não pode ser determinado programaticamente.

Modelo

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

Visão

<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>

Você pode adicionar um @checkedargumento ao objeto anônimo para definir o botão de opção como padrão:

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

Observe que você pode vincular a uma sequência substituindo truee falsepelos valores da sequência.

Daniel Imms
fonte
Você realmente deve usar o novo {id = Html.Id ("married-true")}, reduzindo possíveis problemas de escopo dos prefixos de ID gerados.
eoleary
26

Construindo um pouco da resposta de Ben, adicionei atributos para o ID para poder usar rótulos.

<%: 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" })%>

Eu espero que isso ajude.

ctc
fonte
7
Normalmente, o rótulo está atrás de um botão de opção.
precisa saber é o seguinte
6
Colocar uma etiqueta em torno de um botão de opção é perfeitamente válido.
Scott Baker
23

Adicionar tags de etiqueta nos botões de opção usando HTML comum também corrigirá o problema 'labelfor':

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

Clicar no texto agora seleciona o botão de opção apropriado.

Jeff Bobish
fonte
8

ou MVC 2.0:

<%= Html.RadioButtonFor(model => model.blah, true) %> Yes
<%= Html.RadioButtonFor(model => model.blah, false) %> No
Stafford Williams
fonte
5

Se eu conseguir jogar meu chapéu no ringue, acho que há uma maneira mais limpa do que as respostas existentes de reutilizar a funcionalidade dos botões de opção.

Digamos que você tenha a seguinte propriedade no seu ViewModel :

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

Você pode expor essa propriedade através de um modelo de editor reutilizável :

Primeiro, crie o arquivo Views/Shared/EditorTemplates/YesNoRadio.vbhtml

Em seguida, adicione o seguinte código ao 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>

Você pode chamar o editor para a propriedade especificando manualmente o nome do modelo em sua Visualização :

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

Prós:

  • Comece a escrever HTML em um editor de HTML em vez de anexar seqüências de caracteres no código por trás.
  • Preserva o DisplayName DataAnnotation
  • Permite que cliques no rótulo alternem o botão de opção
  • Menos código possível para manter no formulário (1 linha). Se algo estiver errado com a forma como está renderizando, aceite o modelo.
KyleMit
fonte
Isso é bom, mas e uma terceira opção para booleano? @ Html.RadioButtonFor (Função (Modelo) Model.IsVerified, True) <span> Sim </span> @ Html.RadioButtonFor (Função (Modelo) Model.IsVerified, False) <span> Não </span> @ Html.RadioButtonFor (Função (Model) Model.IsVerified, Nothing)) <span> Pendente </span>
JoshYates1980 11/16/16
1

Acabei empacotando isso em um método de extensão para (1) gerar o rótulo e o rádio de uma só vez e (2) para não ter que me preocupar em especificar meus próprios IDs:

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());
    }
}

Uso:

@Html.RadioButtonAndLabelFor(m => m.IsMarried, true, "Yes, I am married")
ataque
fonte