I have a bunch of checkboxes that are used for the user to specify which columns they want to see on a grid:
The Html.CheckBox
method has a strange implementation. Checkboxes will have a unique name
, and essentially a true/false
value. This is so that the value will easily map to a bool
parameter in an Action.
As you have obviously noticed, this makes for a tricky situation when your checkboxes are dynamic.
The solution is to generate your own checkboxes, all using a common name
and having unique value
s. These will map very nicely into your Action!
See this question too, for some great examples and explanations.
Here's the desired Action:
public ActionResult SetSelectedColumns(string[] selectedColumns) {
// selectedColumns will contain the keys of all the checked columns.
}
And here's how to get your HTML to map correctly:
I highly recommend putting this functionality into an extension method, so that you can also incorporate ModelState
and htmlAttributes
. Here's my untested attempt:
public static HtmlString CheckBoxAlt(this HtmlHelper html, string name, string value, bool selected, object htmlAttributes)
{
var tag = new TagBuilder("input");
if (htmlAttributes != null)
tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
tag.MergeAttribute("type", "checkbox");
tag.MergeAttribute("name", name);
tag.MergeAttribute("value", value);
// Determine if this check should be selected:
var state = html.ViewData.ModelState[name];
if (state != null)
{
var values = (string[])state.Value.ConvertTo(typeof(string[]));
selected = Array.IndexOf(values, value) != -1;
}
if (selected)
tag.MergeAttribute("checked", "checked");
return new HtmlString(tag.ToString(TagRenderMode.SelfClosing));
}