Although it appears to be rather simple taks to add a checkbox list for multiselect items in MVC, in reality it takes a bit of time to get around the concepts and limitations of the framework. So here is a step-by-step list to save the exploration time.
Disclaimer: This article uses techniques mentioned in the last answer at https://stackoverflow.com/questions/40160998/checkboxlist-using-asp-net-mvc-5
- I had two lists in the controller, one list of all possible values and another of the selected items. To be able to display all values from one list and pre-select only those which were present in the second list, it is very convenient to use a CheckboxViewModel class as explained in the last answer of above post.
- I also added one more property to the CheckboxViewModel class which stores id of the object to which it belongs, thus this simplifies the process of generating entities for database update.
- I found out that IEnumerable<CheckboxViewModel> for checkbox binding in view fails to bind values properly in postback methods, so I changed the property type to CheckboxViewModel[].
- Need to add hidden fields for each of the property of CheckboxViewModel class.
public class CheckboxViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
public int ParentId { get; set; }
}
And final extension method looks like
public static CheckboxViewModel[] CreateCheckboxList<T>(this IEnumerable<T> entities, Func<T, int> value, Func<T, object> text, Func<T, bool> isChecked, Func<T, int> parentId)
{
return entities.Select(x => new CheckboxViewModel
{
Id = (int)value(x),
Name = text(x).ToString(),
Checked = isChecked(x),
ParentId = parentId(x)
}).ToArray();
}
View looks like
<div class="form-group">
<div class="checkbox checkbox-primary">
@Html.HiddenFor(model => model.MyCheckboxList[i].Id)
@Html.CheckBoxFor(model => model.MyCheckboxList[i].Checked)
@Html.HiddenFor(model => model.MyCheckboxList[i].Checked)
@Html.LabelFor(model => model.MyCheckboxList[i].Checked, Model.MyCheckboxList[i].Name)
@Html.HiddenFor(model => model.MyCheckboxList[i].Name)
@Html.HiddenFor(model => model.MyCheckboxList[i].ParentId)
</div>
</div>
No comments:
Post a Comment