ASP.NET MVC Yes/No Radio Buttons with Strongly Bound Model MVC
Asked Answered
P

8

141

Does anyone know how to bind a Yes/No radio button to a boolean property of a Strongly Typed Model in ASP.NET MVC.

Model

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

View

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

Thanks

SOLUTION:

Thanks for Brian for the direction but it was the opposite of what he wrote. As so -

<%@  Page Title="blah"  Inherits="MyClass"%>
<dd>
    <%= Html.RadioButton("blah", !Model.blah) %> Yes
    <%= Html.RadioButton("blah", Model.blah) %> No
</dd>
Precincts answered 1/4, 2010 at 8:55 Comment(2)
The "problem" with these solutions (and I'm using the Ben Cull style in my project) is that you can't do labels with them. Both radio button inputs will have the same id and name, so if you you use Html.LabelFor, it will link to the first radio button input in the DOM with that id. Like I said, I'm using this solutions for radio buttons to represent a boolean field, I just wanted people to know that labels will be a bit wonky.Thenceforth
See Jeff Bobish's answer to see how to fix the label issue elegantly.Dustcloth
P
77

The second parameter is selected, so use the ! to select the no value when the boolean is false.

<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 
Pistoleer answered 1/4, 2010 at 10:5 Comment(0)
A
206

If you're using MVC 3 and Razor you can also use the following:

@Html.RadioButtonFor(model => model.blah, true) Yes
@Html.RadioButtonFor(model => model.blah, false) No
Abalone answered 16/11, 2010 at 4:16 Comment(0)
P
77

The second parameter is selected, so use the ! to select the no value when the boolean is false.

<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 
Pistoleer answered 1/4, 2010 at 10:5 Comment(0)
L
60

Here is a more complete example using a fieldset for accessibility reasons and specifying the first button as the default. Without a fieldset, what the radio buttons are for as a whole can not be programmatically determined.

Model

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

View

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

You can add a @checked argument to the anonymous object to set the radio button as the default:

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

Note that you can bind to a string by replacing true and false with the string values.

Lemaster answered 5/6, 2012 at 22:41 Comment(1)
You should actually use new { id = Html.Id("married-true") }, reducing potential scope issues of generated id prefixes.Sealed
M
26

Building slightly off Ben's answer, I added attributes for the ID so I could use labels.

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

I hope this helps.

Muscarine answered 24/1, 2012 at 22:44 Comment(2)
Normally the label is after a radio button.Lemaster
Putting a label around a radio button is perfectly valid.Fourdrinier
M
23

Adding label tags around the radio buttons using regular HTML will fix the 'labelfor' issue as well:

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

Clicking on the text now selects the appropriate radio button.

Medeah answered 5/3, 2012 at 14:56 Comment(0)
L
8

or MVC 2.0:

<%= Html.RadioButtonFor(model => model.blah, true) %> Yes
<%= Html.RadioButtonFor(model => model.blah, false) %> No
Lamed answered 20/7, 2011 at 6:41 Comment(0)
P
5

If I can throw my hat into the ring, I think there is a cleaner way than the existing answers to reuse the radio button functionality.

Let's say you have the following property in your ViewModel:

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

You can expose that property through a reusable editor template:

First, create the file Views/Shared/EditorTemplates/YesNoRadio.vbhtml

Then add the following code to 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>

You can call the editor for the property by manually specifying the template name in your View:

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

Pros:

  • Get to write HTML in an HTML editor instead of appending strings in code behind.
  • Preserves the DisplayName DataAnnotation
  • Allows clicks on Label to toggle radio button
  • Least possible code to maintain in form (1 line). If something is wrong with the way it is rending, take it up with the template.
Pushy answered 14/11, 2014 at 18:27 Comment(1)
This is good, but what about a Third option for Boolean? @Html.RadioButtonFor(Function(Model) Model.IsVerified, True) <span>Yes</span> @Html.RadioButtonFor(Function(Model) Model.IsVerified, False) <span>No</span> @Html.RadioButtonFor(Function(Model) Model.IsVerified, Nothing)) <span>Pending</span>Pretorius
E
1

I ended up packaging this into an extension method so (1) I could generate the label and radio at once and (2) so I didn't have to fuss with specifying my own 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());
    }
}

Usage:

@Html.RadioButtonAndLabelFor(m => m.IsMarried, true, "Yes, I am married")
Etoile answered 3/10, 2014 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.