How can I override the name attribute of a RadioButtonFor?

Asgeir picture Asgeir · Jun 14, 2012 · Viewed 8k times · Source

I'm trying to group together radiobuttons that are creating using a for loop and Razor syntax. Here is the code:

       @for (var i = 0; i < Model.Sessions.Count(); i++)
       {
            @Html.HiddenFor(it => it.Sessions[i].Id)
            @Html.RadioButtonFor(it => it.Sessions[i].Checkbox, "0", new {@class = "Sessions", @id = id, @name="Sessions"})
            @Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
            <span class="time-span"><em>@Model.Sessions[i].StartTime</em><em>@Model.Sessions[i].EndTime</em></span>
            <br />
       }

The third line inside the for loop is where the problem is. Basically the name doesn't change and it's always "Sessions[x].Checkbox". The checkbox is a property (bool) of a custom class. I can't seem to get the hang of debugging Razor stuff, so any help would be greatly appreciated, I'm guessing this will be extremely obvious to someone here.

EDIT Dimitrov's post helped a lot. Below is the final code I used. I use the @class and @id attributes to be able to use Javascript to select the session originally picked (since this is an edit, not create form).

    @for (var i = 0; i < Model.Sessions.Count(); i++)
    {
        @Html.HiddenFor(it => it.Sessions[i].Id)
        var SId = @Model.Sessions[i].Id;
        @Html.RadioButtonFor(it => it.selectedSession, Model.Sessions[i].Id, new { id = SId, @class = "Sessions" })
        @Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
        <span class="time-span"><em>@Model.Sessions[i].StartTime</em><em>@Model.Sessions[i].EndTime</em></span>
        <br />
    }

Answer

Darin Dimitrov picture Darin Dimitrov · Jun 14, 2012

If you want to be able to select only a single radio button you need to have a single property on your view model to hold the selected session id, like this:

public class SessionViewModel
{
    public int SelectedSessionId { get; set; }
    public IList<Session> Sessions { get; set; }
}

public class Session
{
    public int Id { get; set; }
    public string Name { get; set; }
}

and then have a controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new SessionViewModel
        {
            SelectedSessionId = 2,
            Sessions = Enumerable.Range(1, 5).Select(x => new Session
            {
                Id = x,
                Name = "session" + x,
            }).ToList()
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(SessionViewModel model)
    {
        return Content("Thank you for selecting session id: " + model.SelectedSessionId);
    }
}

and finally a view:

@model SessionViewModel

@using (Html.BeginForm())
{
    for (var i = 0; i < Model.Sessions.Count(); i++)
    {
        @Html.HiddenFor(x => x.Sessions[i].Id)
        @Html.RadioButtonFor(x => x.SelectedSessionId, Model.Sessions[i].Id, new { id = "session_" + i })
        @Html.Label("session_" + i, Model.Sessions[i].Name)
        <br/>
    }
    <button type="submit">OK</button>
}