Reputation: 14204
I'm working on an ASP.NET MVC app. In this app, I'm am working to create a checkbox list on top of a custom object. The custom object looks like this:
public class ListItem<TId, TLabel, TIsChecked>
{
private TId id;
private TLabel label;
private TIsChecked isChecked;
public ListItem(TId id, TLabel label, TIsChecked isChecked)
{
this.id = id;
this.label = label;
this.isChecked = isChecked;
}
public TId Id
{
get { return id; }
}
public TLabel Label
{
get { return label; }
}
public TIsChecked IsChecked
{
get { return isChecked; }
}
}
I have a model that looks like this:
public class MyModel
{
public IEnumerable<ListItem<Guid, string, bool>> Options { get; set; }
}
I then have a controller, with an action called Profile, that looks like this:
[HttpGet]
public ActionResult Profile()
{
var model = new MyModel();
return View(model);
}
[HttpPost]
public ActionResult Profile(MyModel model)
{
return View(model);
}
I am rendering my checkbox options in my Razor view like this:
@foreach (var option in Model.Options)
{
<div class="form-group">
<div class="checkbox">
<label>
<input name="Options" value="@option.Id" type="checkbox" @((option.IsChecked == true) ? "checked" : string.Empty)> @option.Label
</label>
</div>
</div>
}
The options render fine. But, when I save the form, it looks like only the first selected checkbox ID is returned. I'm not sure how to a) properly render my HTML for a checkbox list and b) get the values to properly post back to the server. I've seen other examples in blog posts, but, my view will have significantly more HTML. For that reason, I'm trying to figure out "how" checkbox values are rendered on the client-side and posted back to the server in ASP.NET MVC.
Upvotes: 0
Views: 1868
Reputation: 62488
First you have to do change in your model to use List<T>
instead of IEnumerable<T>
:
public List<ListItem<Guid, string, bool>> Options { get; set; }
Secondly, you do not have setters for your properties, so data would not be posted back, add setters:
public TId Id
{
get { return id; }
set { id = value;}
}
public TLabel Label
{
get { return label; }
set { label = value;}
}
public TIsChecked IsChecked
{
get { return isChecked; }
set { isChecked = value;}
}
and at last you simply need to use strongly typed html helper and use for loop so that indexing can bind data for post:
@for(int i=0; i< Model.Options.Count; i++)
{
<div class="form-group">
<div class="checkbox">
<label>
@Html.CheckBoxFor(model => model.Options[i].IsChecked) @Model.Options[i].Label
</label>
@Html.HiddenFor(model=> model.Options[i].Id)
@Html.HiddenFor(model=> model.Options[i].Label)
</div>
</div>
}
This will create check-boxes with correct names so that they can be binded on post.
You might want to have a look on How List binding works
Upvotes: 1