Datoon
Datoon

Reputation: 574

MVC 3, Radio buttons & Models

Given I have a Model object like ...

public class MyModel
{
  public int SomeProperty { get; set; }
  public int SomeOtherProperty { get; set; } 

  public IList<DeliveryDetail> DeliveryDetails { get; set; }
}

public DeliveryDetail
{
   public string Description { get; set; }
   public bool IsSelected { get; set; }
}

and I pass it through to a View like this ...

// Controller
public ActionResult Index()
{
  MyModel myModel = Factory.CreateModelWithDeliveryDetails(x);
  return View(myModel);
}

How would I render / bind a set of radio buttons (in the view)? Using the following code doesn't post the data back:

@foreach(var deliveryDetail in @Model.DeliveryDetails)
{
   @deliveryDetail.Description
   @Html.RadioButtonFor(x => deliveryDetail, false)
}

Upvotes: 3

Views: 8880

Answers (2)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039438

Selections in a radio button list are mutually exclusive. You can select only a single value. So binding a radio button list to a property of type IEnumerable doesn't make any sense. You probably need to adapt your view model to the requirements of the view (which in your case is displaying a radio button list where only a single selection can be made). Had you used a checkbox list, binding to an IEnumerable property would have made sense as you can check multiple checkboxes.

So let's adapt the view model to this situation:

Model:

public class MyModel
{
    public string SelectedDeliveryDetailId { get; set; }
    public IList<DeliveryDetail> DeliveryDetails { get; set; }
}

public class DeliveryDetail
{
   public string Description { get; set; }
   public int Id { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyModel
        {
            DeliveryDetails = new[]
            {
                new DeliveryDetail { Description = "detail 1", Id = 1 },
                new DeliveryDetail { Description = "detail 2", Id = 2 },
                new DeliveryDetail { Description = "detail 3", Id = 3 },
            }
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyModel model)
    {
        // Here you will get the id of the selected delivery detail
        // in model.SelectedDeliveryDetailId
        ...
    }
}

View:

@model MyModel

@using (Html.BeginForm())
{
    foreach (var deliveryDetail in Model.DeliveryDetails)
    {
       @deliveryDetail.Description
       @Html.RadioButtonFor(x => x.SelectedDeliveryDetailId, deliveryDetail.Id)
    }
    <button type="submit">OK</button>
}

Upvotes: 8

PanJanek
PanJanek

Reputation: 6685

You need another property for posted value::

public class MyModel
{
  public int SomeProperty { get; set; }
  public int SomeOtherProperty { get; set; } 

  public IList<DeliveryDetail> DeliveryDetails { get; set; }

  public DeliveryDetail SelectedDetail { get; set; }
}

And in view:

@foreach(var deliveryDetail in @Model.DeliveryDetails)
{
   @deliveryDetail.Description
   @Html.RadioButtonFor(x => x.SelectedDetail, deliveryDetail)
}

In order this to work DeliveryDetail has to be Enum.

Upvotes: 1

Related Questions