Introduction
ASP.NET MVC3 does not provide built in control for implementing CheckBoxList. While working in my project I was assigned a User Story which required such an implementation. After searching a lot on net I did not find the feasible solution. Hence, I tried this on my own and have banged my head a lot of times while implementing. Well, this is my first article, hence excuse me for any my mistakes and also help rectify them.
Background
This implementation is on asp.net MVC3, NHibernate, linq. Best suited for fixed size CheckBoxList.
Using the code
In the Model class, include the enum for which CheckBoxList is to be created. Enum value should be of the order 2^n as shown below.
[Flags]public enum ReportTemplateFormat
{
PDF = 1,
Excel = 2,
Word = 4,
CSV = 8
}
Include another enum which has values similar to below.
public enum ReportFormat
{
PDF = 0,
Excel = 1,
Word = 2,
CSV = 3
}
Include bool list in the ViewModel.
public List<bool> ReportFormats { get; set; }
In the Model, include an int property. Same to be included in the database.
public virtual int AvailableFormats { get; set; }
In the create viewmodel from the model:
• When creating viewmodel, pass AvailableFormats(int) from model and assign to List<bool> used for checking the checkbox
viewModel.ReportFormats = GetFormats(model.AvailableFormats);
• Method to return List<bool> from the AvailableFormats(int) value passed.
public List<bool> GetFormats(int reportFormats)
{
var reportTemplateFormat = new List<bool>();
var reportTemplateFormatValues = (ReportTemplateFormat[])Enum.GetValues(typeof(ReportTemplateFormat));
if(reportFormats==0)
{
for (var i = 0; i < reportTemplateFormatValues.Count(); i++)
{
reportFormats += (int)reportTemplateFormatValues[i];
}
}
for (var i = 0; i < reportTemplateFormatValues.Count(); i++)
{
reportTemplateFormat.Add(new bool());
}
foreach (var x in reportTemplateFormatValues)
{
if ((int)x != 0 && (reportFormats & (int)x) == (int)x)
{
ReportFormat reportFormat;
if (Enum.TryParse(x.ToString(), true, out reportFormat))
{
reportTemplateFormat[(int)reportFormat] = true;
}
else
{
throw new ArgumentException(string.Format("Invalid Format '{0}'!", x));
}
}
}
return reportTemplateFormat;
}
In update model from viewmodel
• Update the AvailableFormats property in the model by passing the List<bool> which contains the checked values from the checkbox list.
model.AvailableFormats = GetAvailableFormats(viewModel.ReportFormats);
• Pass the List<bool> and return the evaluated AvailableFormats to be saved to model.
public int GetAvailableFormats(List<bool> reportTemplateFormats)
{
int reportTemplateFormat = 0;
var reportTemplateValues = (ReportTemplateFormat[]) Enum.GetValues(typeof (ReportTemplateFormat));
for (int i = 0; i < reportTemplateFormats.Count; i++)
{
if (reportTemplateFormats[i])
reportTemplateFormat += Convert.ToInt32(reportTemplateValues[i]);
}
return reportTemplateFormat;
}
• Implementation of the CheckBoxList in view.
<div class="float-editor-row">
<div class="float-editor-label">@Html.Label("* Report Format")</div>
<div class="float-editor-field">
@for (var i = 0; i < Model.ReportFormats.Count; i++)
{
//Using ReportFormats List<bool> to check the checkbox
@Html.CheckBoxFor(x => x.ReportFormats[i], new { @checked = "checked" })
@Html.LabelFor(x => x.ReportFormats[i], ((ReportFormat)i).ToString())<text> </text>
}
</div>
</div>
Points of Interest
Well, this is my first article and I am sure there's lot of mistakes. Its very nice to share knowledge with everyone, thats the way even I have and thanks to all of them. I am open to criticism and please suggest me the points to improve myself and my writing skills.
History
This was implemented in my current project. Soon I would like to create basic project based on the comments.
Thanks,
Suhas S