mvc radiobuttons in foreach
Asked Answered
H

3

8

I'm using MVC and I have some RadioButtons in a foreach:

    foreach (var item in group) {
                    <tr>
                        <td>
                            @Html.RadioButtonFor(modelItem => item.CheckerApproved, true)
                            @Html.RadioButtonFor(modelItem => item.CheckerApproved, false)
                        </td>
                    </tr>
}

So for every item in the group there should be a radiobutton for true and false.

The problem is when there are multiple items in the group you might end up with for two items:

<tr>
   <td>
      <input id="item_CheckerApproved" type="radio" value="True" name="item.CheckerApproved">
      <input id="item_CheckerApproved" type="radio" value="False" name="item.CheckerApproved 
         checked="checked">
   </td>
</tr>

<tr>
   <td>
      <input id="item_CheckerApproved" type="radio" value="True" name="item.CheckerApproved">
      <input id="item_CheckerApproved" type="radio" value="False" name="item.CheckerApproved 
         checked="checked">
   </td>
</tr>

What I wanted was for the radiobuttons groups to be seperate. So changing the value in the first row won't effect the value in the second row. However if you have set say true in the top row then select either value in the second row the true in the first row is cancelled.

I believe this is because they are linked by the name attribute. However you can't actually manually reset this name attribute.

Does anyone know how I could make it work so the true and false for each row interact with each other but there is no effect on radiobuttons in other rows?

Herron answered 5/10, 2011 at 20:44 Comment(1)
This sort of explains what's going on : blog.hmobius.com/post/2008/08/14/…Herron
H
15

Don't write loops in views. They are ugly and you end up with undesired behavior as the one described in your question. Use editor templates, like this:

<table>
    <thead>
        <tr>
            <th>Approved status</th>
        </tr>
    </thead>
    <tbody>
         @Html.EditorFor(x => x.Groups)
    </tbody>
</table>

Here I assume that your view model has a Groups collection property of type IEnumerable<GroupViewModel>. Now all that's left is to write the corresponding editor template which will be executed for each element in the Groups collection (~/Views/Shared/EditorTemplates/GroupViewModel.cshtml):

@model GroupViewModel
<tr>
    <td>
        @Html.RadioButtonFor(x => x.CheckerApproved, "true") <span>Approved</span>
        @Html.RadioButtonFor(x => x.CheckerApproved, "false") <span>Not approved</span>
    </td>
</tr>

Now not only that you no longer need to write any ugly foreach loops in your view but you end up with correct naming convention.

Hakon answered 5/10, 2011 at 22:5 Comment(2)
Ok, great thanks it's working exactly as I want it and is much tidier. Thanks heaps for your suggestionHerron
Where do you put (~/Views/Shared/EditorTemplates/GroupViewModel.cshtml):?Lukasz
B
2

One way is to use a for loop and RadioButton instead of RadioButtonFor

@for (int i = 0; i < item.Count; i++)
{
    <tr>
        <td>
            @Html.RadioButton("item_CheckerApproved_" + i, true, item[i].CheckerApproved)
            @Html.RadioButton("item_CheckerApproved_" + i, false, !item[i].CheckerApproved)
        </td>
    </tr>
}
Bocage answered 5/10, 2011 at 21:59 Comment(1)
I do like the simplicity of this answer but it only allows access to the data via the FormCollection and not the view model. Darin Dimitrovs's accepted answer does however provide the data via the view model.Fishbowl
B
0

One way how to use radiobuttons in foreach

 @{
    int i = 0;
    foreach(var item in group)
      { 
         i++;
       <tr>
       <td>
          <input id="item_CheckerApproved" type="radio" value="True" name="item.CheckerApproved_@i">
          <input id="item_CheckerApproved" type="radio" value="False" name="item.CheckerApproved_@i 
             checked="checked">
       </td>
    </tr>

    <tr>
       <td>
          <input id="item_CheckerApproved" type="radio" value="True" name="item.CheckerApproved_@i">
          <input id="item_CheckerApproved" type="radio" value="False" name="item.CheckerApproved_@i 
             checked="checked">
       </td>
    </tr>
      }

    }

Hope it helps ;)

Baram answered 20/10, 2015 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.