Multiple radio button groups in MVC 4 Razor
Asked Answered
T

5

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;}
}
Tana answered 4/3, 2014 at 14:19 Comment(1)
possible duplicate of how to show and use Radio button in Asp.Net MVC3Maurist
T
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 ;)

Tana answered 4/3, 2014 at 17:23 Comment(0)
S
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")
Shears answered 4/3, 2014 at 14:26 Comment(11)
Yeah, but the problem is that each group's radios are created in a foreach() in my code.Tana
can you show your foreach and we can see if there is a way to get it to work?Shears
Of course ! I just edited my post. Please have a look.Tana
see here #18040974 and here https://mcmap.net/q/426517/-mvc-radiobuttons-in-foreachShears
Thank you very much Matt Bodily! Your references helped me fix this problem, although in a different way. I appreciate your helpTana
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.Leprose
@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)Shears
@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.Leprose
@JonathanWood have you tried using the labelfor helper? You are right. it will have the same name and shouldn't have the same idShears
@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 #27728488Leprose
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")Allow
T
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 ;)

Tana answered 4/3, 2014 at 17:23 Comment(0)
G
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!

Gob answered 30/12, 2014 at 17:45 Comment(0)
U
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
Unveiling answered 11/7, 2018 at 16:51 Comment(0)
A
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

Aalesund answered 4/3, 2014 at 15:37 Comment(1)
Sorry, I have no idea how to do it :/ Is there any reference or example showing how I can do it ?Tana

© 2022 - 2024 — McMap. All rights reserved.