2

Say I have the following properties in my model that I want to be mutually exclusive:

public bool PrintWeek1 {get; set;}
public bool PrintWeek2 {get; set;}
public bool PrintWeek3 {get; set;} 

Is it possible to render these as a set of radio buttons or do I need to change them to an enum?

If I use @Html.RadioButtonFor it renders name as the name of the property so they aren't grouped correctly.

woggles
  • 7,444
  • 12
  • 70
  • 130
  • you can give your own name - `new { @Name= "grp" }`, so that they will be grouped together. – ramiramilu Jun 24 '15 at 07:47
  • try this http://stackoverflow.com/a/3122130/3664659 – Imad Jun 24 '15 at 07:48
  • A single enum property (with 3 values and 3 corresponding radio buttons) would make more sense –  Jun 24 '15 at 07:49
  • @ramiramilu ah i was trying with `new {@name = "grp"}` which wasn't overwriting the name MVC was rendering. I'll check now if they post back correctly.. – woggles Jun 24 '15 at 07:50
  • 1
    Actually it works for mutually exclusiveness, But changing the name would actually create problems in `posting` the model. How are you actually posting the data back to server? Instead I would suggest you to use `RadioButtonListFor` like shown here - http://stackoverflow.com/questions/21679249/mvc5-enum-radio-button-with-label-as-displayname – ramiramilu Jun 24 '15 at 07:54

2 Answers2

5

Here comes a quick solution, let you have following properties in Model -

public bool PrintWeek1 { get; set; }
public bool PrintWeek2 { get; set; }
public bool PrintWeek3 { get; set; }
public string SelectedValue { get; set; }

Then your HTML should be like this -

@Html.RadioButtonFor(Model => Model.PrintWeek1, "PrintWeek1", new { @Name = "SelectedValue" }) 
@Html.RadioButtonFor(Model => Model.PrintWeek2, "PrintWeek2", new { @Name = "SelectedValue" }) 
@Html.RadioButtonFor(Model => Model.PrintWeek3, "PrintWeek3", new { @Name = "SelectedValue" })

Then when you submit the form, you will get the selected value in SelectedValue property.

EDIT To Address @StephenMuecke point, created the below solution -

Create a enum -

public enum PrintWeekType
{
    PrintWeek1, PrintWeek2, PrintWeek3
}

Then have a model property (instead of individual properties, have single emum property) -

public PrintWeekType SelectedValue { get; set; }

HTML should be like below -

@Html.RadioButtonFor(m => m.SelectedValue, PrintWeekType.PrintWeek1) 
@Html.RadioButtonFor(m => m.SelectedValue, PrintWeekType.PrintWeek2) 
@Html.RadioButtonFor(m => m.SelectedValue, PrintWeekType.PrintWeek3)

Using above sample, one can pre-select a radiobutton, at the same time we can post the selected value in SelectedValue property.

ramiramilu
  • 17,044
  • 6
  • 49
  • 66
  • 1
    This wont work and give 2 way model binding. When the view is first rendered, no radio buttons will ever be selected, irrespective of the value of the `boolean` properties –  Jun 24 '15 at 08:22
  • 1
    @StephenMuecke You are right, updated my answer with more precise solution :-) – ramiramilu Jun 24 '15 at 09:33
1

Ok I abandoned the bools and just ended up using a list - this seemed to be the quickest and easiest way to do it.

Where I initialize my model:

   public PrintViewModel()
        {
            this.PrintTypes = new List<string>() { "Print Week 1", "Print Week 2", "Print Week 3" };
        }

    public List<string> PrintTypes { get; set; }
    public string SelectedPrintType { get; set; }

In my view (I wanted the first option selected by default):

   @for(int i = 0; i < Model.PrintTypes.Count; i++)
        {
            <div class="row">
                <div class="col-md-2">
                    @(i == 0 ? Html.RadioButtonFor(x => x.SelectedPrintType, Model.PrintTypes[i], new {@checked = "checked"}) : @Html.RadioButtonFor(x => x.SelectedPrintType, Model.PrintTypes[i]))
                    &nbsp;
                    <label for="@Model.PrintTypes[i]">@Model.PrintTypes[i]</label>
                </div>
            </div>
        }
woggles
  • 7,444
  • 12
  • 70
  • 130