37

I need to have multiple radio button groups in my form like this:
enter image description here

I know it's simply done by specifying the same "name" html attribute for each group.
HOWEVER
MVC doesn't let you specify your own name attribute when using html helper like this:

@Html.RadioButtonFor(i => item.id, item.SelectedID, new { Name = item.OptServiceCatId })  

Because it looks at each tag's "name" attribute (not "id") to map/bind the form to the model which the controller receives, etc.

Some said that specifying each with the same "GroupName" attribute will solve the problem, but it didn't work either.

So, is there any way which works ?

EDIT:
Here's my view (simplified):

@model Service_Provider.ViewModels.SelectOptServicesForSubServiceViewModel

@foreach (var cat in Model.OptServices)
{
  //A piece of code & html here
  @foreach (var item in cat.OptItems.Where(i => i.MultiSelect == false))
  {
     @Html.RadioButtonFor(i => item.id, item.SelectedID, new { GroupName = item.OptServiceCatId })
<br />
  }    
}

NOTE:
My model is a List<OptServices>:

public List<OptServices> Cats {get; set;}

And OptServices has a List of OptItems inside:

public class OptServices
{
//a few things
public List<OptItems> Items {get; set;}
}
ekad
  • 14,436
  • 26
  • 44
  • 46
Ali
  • 1,152
  • 2
  • 14
  • 33
  • possible duplicate of [how to show and use Radio button in Asp.Net MVC3](http://stackoverflow.com/questions/8560659/how-to-show-and-use-radio-button-in-asp-net-mvc3) – bummi Sep 13 '14 at 07:33

5 Answers5

31

all you need is to tie the group to a different item in your model

@Html.RadioButtonFor(x => x.Field1, "Milk")
@Html.RadioButtonFor(x => x.Field1, "Butter")

@Html.RadioButtonFor(x => x.Field2, "Water")
@Html.RadioButtonFor(x => x.Field2, "Beer")
Matt Bodily
  • 6,403
  • 4
  • 29
  • 48
  • 3
    Yeah, but the problem is that each group's radios are created in a foreach() in my code. – Ali Mar 04 '14 at 15:02
  • can you show your foreach and we can see if there is a way to get it to work? – Matt Bodily Mar 04 '14 at 15:03
  • Of course ! I just edited my post. Please have a look. – Ali Mar 04 '14 at 16:11
  • 2
    see here http://stackoverflow.com/questions/18040474/group-radio-buttons-in-foreach-loop-in-mvc-razor-view and here http://stackoverflow.com/questions/7667495/mvc-radiobuttons-in-foreach – Matt Bodily Mar 04 '14 at 16:21
  • Thank you very much Matt Bodily! Your references helped me fix this problem, although in a different way. I appreciate your help – Ali Mar 04 '14 at 17:07
  • Uh, how is this useful? In my tests, this displays no label for the radio buttons. Also, it creates multiple radio buttons with the same ID. – Jonathan Wood Jan 01 '15 at 18:12
  • @JonathanWood this example doesn't have labels. you would need to add them. just a label tag. this will create multiple radio buttons with the same id. The one that is clicked will set the value and the passed back value of the radio button will be the one that was selected (if the first one is clicked the value of Field1 in the post back will be Milk) – Matt Bodily Jan 04 '15 at 02:32
  • @MattBodily: Did you mean the same *name* attribute? They should have the same name, there should never be more than one element with the same ID. Anyway, I just found radio buttons with **clickable** labels just very awkward in MVC. I've been researching it for days, and am just not finding a clean solution. – Jonathan Wood Jan 04 '15 at 04:30
  • @JonathanWood have you tried using the labelfor helper? You are right. it will have the same name and shouldn't have the same id – Matt Bodily Jan 04 '15 at 04:32
  • @MattBodily: Yes, and I can make it work. But it requires non-standard coding, and has issues. For more info, you can see my question http://stackoverflow.com/questions/27727988/correct-way-to-code-a-group-of-radio-buttons-using-radiobuttonfor – Jonathan Wood Jan 04 '15 at 05:01
  • A similar solution might work. Instead of using @Html.RadioButtonFor(x => x.Field1, "Milk") and @Html.RadioButtonFor(x => x.Field2, "Water"), you could use the old version of the @Html helper in combination with a counter. That way you could use it in a loop. Eg., @Html.RadioButton("Field"+fieldCounter, "Water") – Mate Šimović Jan 29 '17 at 16:11
19

Ok here's how I fixed this

My model is a list of categories. Each category contains a list of its subcategories.
with this in mind, every time in the foreach loop, each RadioButton will have its category's ID (which is unique) as its name attribue.
And I also used Html.RadioButton instead of Html.RadioButtonFor.

Here's the final 'working' pseudo-code:

@foreach (var cat in Model.Categories)
{
  //A piece of code & html here
  @foreach (var item in cat.SubCategories)
  {
     @Html.RadioButton(item.CategoryID.ToString(), item.ID)
  }    
}

The result is:

<input name="127" type="radio" value="110">

Please note that I HAVE NOT put all these radio button groups inside a form. And I don't know if this solution will still work properly in a form.

Thanks to all of the people who helped me solve this ;)

Daniel Williams
  • 8,912
  • 15
  • 68
  • 107
Ali
  • 1,152
  • 2
  • 14
  • 33
4

I fixed a similar issue building a RadioButtonFor with pairs of text/value from a SelectList. I used a ViewBag to send the SelectList to the View, but you can use data from model too. My web application is a Blog and I have to build a RadioButton with some types of articles when he is writing a new post.

The code below was simplyfied.

List<SelectListItem> items = new List<SelectListItem>();

Dictionary<string, string> dictionary = new Dictionary<string, string>();

dictionary.Add("Texto", "1");
dictionary.Add("Foto", "2");
dictionary.Add("Vídeo", "3");

foreach (KeyValuePair<string, string> pair in objBLL.GetTiposPost())
{
    items.Add(new SelectListItem() { Text = pair.Key, Value = pair.Value, Selected = false });
}

ViewBag.TiposPost = new SelectList(items, "Value", "Text");

In the View, I used a foreach to build a radiobutton.

<div class="form-group">
    <div class="col-sm-10">
        @foreach (var item in (SelectList)ViewBag.TiposPost)
        {
            @Html.RadioButtonFor(model => model.IDTipoPost, item.Value, false)
            <label class="control-label">@item.Text</label>
        }

    </div>
</div>

Notice that I used RadioButtonFor in order to catch the option value selected by user, in the Controler, after submit the form. I also had to put the item.Text outside the RadioButtonFor in order to show the text options.

Hope it's useful!

Marcelo Sader
  • 331
  • 4
  • 12
2

I was able to use the name attribute that you described in your example for the loop I am working on and it worked, perhaps because I created unique ids? I'm still considering whether I should switch to an editor template instead as mentioned in the links in another answer.

    @Html.RadioButtonFor(modelItem => item.Answers.AnswerYesNo, "true", new {Name = item.Description.QuestionId, id = string.Format("CBY{0}", item.Description.QuestionId), onclick = "setDescriptionVisibility(this)" }) Yes

    @Html.RadioButtonFor(modelItem => item.Answers.AnswerYesNo, "false", new { Name = item.Description.QuestionId, id = string.Format("CBN{0}", item.Description.QuestionId), onclick = "setDescriptionVisibility(this)" } ) No
Anna
  • 21
  • 2
1

You can use Dictonary to map Assume Milk,Butter,Chesse are group A (ListA) Water,Beer,Wine are group B

Dictonary<string,List<string>>) dataMap;
dataMap.add("A",ListA);
dataMap.add("B",ListB);

At View , you can foreach Keys in dataMap and process your action

Dakota
  • 495
  • 2
  • 10
  • Sorry, I have no idea how to do it :/ Is there any reference or example showing how I can do it ? – Ali Mar 04 '14 at 16:13