I had to use an EditorTemplate instead of the conventional Html.CheckBoxFor
for my purposes. In the process, I seemed to have messed up it's binding though. Is there a reason why the following is not binding to an incoming model?
<input data-val="true"
data-val-required="The @Html.Raw(checkSuffix) field is required."
id="@Html.Raw(checkId)"
name="@Html.Raw(checkName)"
type="checkbox"
value="true">
<input name="@Html.Raw(checkName)"
type="hidden"
value="false">
<label for="@Html.Raw(checkId)"
name="@Html.Raw(labelName)">
<span class="fa-stack">
<i class="fa fa-square-o fa-stack-1x"></i>
<i class="fa fa-check fa-stack-1x"></i>
</span>
@Model.Label
@Html.HiddenFor(item => item.Label)
</label>
Note: the model binds properly on posting to the server, just not on page reload or postback.
Edit: Generated HTML:
<input data-val="true" data-val-required="The IsChecked field is required." id="Issues_0__IsChecked" name="Issues[0].IsChecked" type="checkbox" value="true">
<input name="Issues[0].IsChecked" type="hidden" value="false">
<label for="Issues_0__IsChecked" name="Issues[0].Label">
<span class="fa-stack">
<i class="fa fa-square-o fa-stack-1x"></i>
<i class="fa fa-check fa-stack-1x"></i>
</span>
My Transmitting Computer/Server is not working
<input id="Issues_0__Label" name="Issues[0].Label" type="hidden" value="My Transmitting Computer/Server is not working">
</label>
Your attempting to manually create html with gives identical html as the CheckBoxFor()
method, except that you never set the checked
attribute so when the view is displayed (either initially or if you return the view in the POST method) all checkboxes will be unchecked.
You have not posted your models or the view, but it is also clear you not using your EditorTemplate
correctly. Assuming your have the following models
public class MainModel
{
public IEnumerable<NestedModel> Issues { get; set; }
}
public class NestedModel
{
public bool IsChecked { get; set; }
public string Label { get; set; }
}
Then in /Views/Shared/EditorTemplates
create a partial view named NestedModel.cshtml
(note the name must match the name of the class)
@model yourAssembly.NestedModel
@Html.CheckBoxFor(m => m.IsSelected)
<label for="@Html.IdFor(m => m.IsSelected)"> // use IdFor() and no need to add name attribute
<span class="fa-stack">
<i class="fa fa-square-o fa-stack-1x"></i>
<i class="fa fa-check fa-stack-1x"></i>
@Html.DisplayFor(m => m.Label)
</label>
@Html.HiddenFor(m => m.Label)
and then in the main view
@model yourAssembly.MainModel
@using (Html.BeginForm())
{
@Html.EditorFor(m => m.Issues)
...
Note that the EditorFor()
method accepts IEnumerable<T>
and will generate the correct html (with indexers) for each item in the collection.
Its unclear why you have the property Label
which just appears to return "My Transmitting Computer/Server is not working"
. Instead your model should be
public class NestedModel
{
[Display(Name = "My Transmitting Computer/Server is not working")]
public bool IsChecked { get; set; }
}
and in the EditorTemplate
, replace @Html.DisplayFor(m => m.Label)
with @Html.DisplayNameFor(m => m.IsChecked)
and delete the hidden input.
Finally, if your regularly creating <label>
with those icons, consider creating a HtmlHelper extension method so you you can simply use (say) @Html.MyCoolLabel(m => m.IsSelected)
to generate all the html.