If control haven't worked in your MVC3 project, update to latest bugfix v.1.4.2.3!
Install-Package MvcCheckBoxList
Download stable binary version (MvcCheckBoxList.dll)
Download sample MVC3 project with extension's stable source code
Contents
Introduction
One of the cool features of Microsoft MVC web development framework since its inception, was its rich Html helpers library. It provided helpers to create most common html controls like text boxes, drop down lists, text areas, etc. It is done by simply typing Html.<smth> on the MVC view page.
Its all been good and easily customizable, until developers been eventually reaching one blank spot... That spot was a creation of a checkbox lists. There was none, and there is no any control to handle that functionality as of now. Perhaps not until MVC4 will come alive...
To create a checkbox list a developer would have to use a combination of FOR or FOREACH cycle and some html <input> along with it.
While not being a hard thing to do, it could possibly become pretty time consuming. Especially when project was getting bigger and fatter with a whole bunch of repetitive code lying around. And think about adding some advanced functionality and layout. For example, when we want to disable some checkboxes, while at the same time being able to POST it back to your controller, and on top of that, putting it into the <table>, it would become quite bigger than before.
But what if we would want to put it into several columns? It would require even more customization. And would get even bigger. This little extension intends to simplify this task while making it more inline with general MVC workflow.
This plugin is just a simple extension of MVC class 'HtmlHelper', which is used for all Html helpers on MVC views. Since there is no supported CheckBoxList extension built into MVC, this plugin adds it.
Using the code
To use this extension, just download file using the link at the top, and copy it anywhere in your MVC project.
All examples below are shown using MVC3 + Razor view engine. It may also work fine in MVC 1 and 2. But honestly, If you haven't upgraded to MVC3 yet, it's about time you do))
Quick start:
Method 1: Using strongly typed, based on a view model
public class City {
public int Id { get; set; }
public string Name { get; set; }
}
public class Region {
public IList<City> City { get; set; }
}
public class RegionViewModel {
public Region Region { get; set; }
public IList<City> Cities { get; set; }
}
@Html.CheckBoxList("Cities", x => x.Cities, x => x.Id, x => x.Name, x => x.Region.Cities)
@Html.CheckBoxListFor(x => x.Region, x => x.Cities, x => x.Id, x => x.Name, x => x.Region.Cities)
@Html.CheckBoxListFor(x => x.Cities, x => x.Cities, x => x.Id, x => x.Name, x => x.Region.Cities, new { htmlAttribute="somevalue" }, new HtmlListInfo(HtmlTag.vertical_columns, 3),
new[] {"7", "12", "14"})
@Html.CheckBoxListFor(x => x.Region.Cities, x => x.Cities,
x => x.Id,
x => x.Name,
x => x.Region.Cities)
@Html.CheckBoxListFor(x => x.Region.Cities,
x => x.Cities,
x => x.Id,
x => x.Name,
x => x.Region.Cities,
x => x.Tags)
If you are not very familiar with this extension, or it all looks confusing, download and run
Sample MVC3 Project which contains more uselful examples and scenarios (download link at the top)!
To POST selected values back to the controller, it should accept a string array with the same name as CheckBoxList control name:
public class Test {
public int Id { get; set; }
public string Name { get; set; }
}
public class PostedTests {
public string[] Tests { get; set; }
}
public class TestViewModel {
public IList<Test> AvailableTests { get; set; }
public IList<Test> SelectedTests { get; set; }
public PostedTests PostedTests { get; set; }
}
@Html.CheckBoxListFor(x => x.PostedTests.Tests, x => x.AvailableTests,
x => x.Id,
x => x.Name,
x => x.SelectedTests)
[HttpPost]
public ActionResult Edit(int id, PostedTests postedTests) {
var list_of_selected_tests = postedTests.Tests;
return Edit(id);
}
Method 2: Independent from view model
@{
var sourceData = new[] {
new {Name = "Monroe", Id = 1},
new {Name = "Moscow", Id = 2},
new {Name = "New Orleans", Id = 3},
new {Name = "Ottawa", Id = 4},
new {Name = "Mumbai", Id = 5}
};
var dataList = sourceData.Select
(r => new SelectListItem { Value = r.Id.ToString(), Text = r.Name }).ToList();
var selectedValues = new[] { "1", "4" };
var dataListSelected = sourceData.Select
(r => new SelectListItem { Value = r.Id.ToString(), Text = r.Name,
Selected = selectedValues.Any(s => s == r.Id.ToString())}).ToList();
}
@Html.CheckBoxList("Cities", dataList)
@Html.CheckBoxList("MoreCities", dataListSelected)
To POST selected values back to the controller, it should accept a string array with the same name as CheckBoxList control name:
[HttpPost]
public ActionResult Edit(int id, string[] Cities) {
return Edit(id);
}
Advanced examples (for Model-based approach):
We'll create CheckBoxList which is arranged inside formatted list (given that you have created appropriate view model, using strongly typed way, 'x' represents your model).
Create an instance of checkbox list formatting class 'HtmlListInfo' with parameters:
@{ var putCheckBoxesIntoUnorderedList = new HtmlListInfo(HtmlTag.ul);
new HtmlListInfo(HtmlTag.table, 3);
new HtmlListInfo(HtmlTag.vertical_columns, 3);
new HtmlListInfo(HtmlTag.SELECT, NUMBER_OF_COLUMNS, new { htmlTag1 = "Value1", htmlTag2 = "Value2" });
}
Apply an instance of 'HtmlListInfo' class to your checkbox list call:
@Html.CheckBoxList("MyCitiesCheckBoxList",
x => x.Cities,
x => x.Id,
x => x.Name,
x => x.SelectedCities,
putCheckBoxesIntoUnorderedList)
OR use 'CheckBoxListFor' method:
@Html.CheckBoxListFor(x => x.Cities, x => x.Cities,
x => x.Id,
x => x.Name,
x => x.SelectedCities,
putCheckBoxesIntoUnorderedList)
Advanced examples (for Model-independent approach):
Note: You can use display customizations below (using HtmlListInfo class and others)
for Model-based approach too.
@Html.CheckBoxList("Cities", dataList)
@Html.CheckBoxList("Cities", dataList, Position.Vertical)
@{ var putCheckBoxesIntoUnorderedList = new HtmlListInfo(HtmlTag.ul); }
@Html.CheckBoxList("Cities", dataList, putCheckBoxesIntoUnorderedList)
@{ var putCheckBoxesIntoTable = new HtmlListInfo(HtmlTag.table, 3); }
@Html.CheckBoxList("Cities", dataList, putCheckBoxesIntoTable)
@{
var putCheckBoxesIntoTable =
new HtmlListInfo(HtmlTag.vertical_columns, 4, new { style = "width:100px;" });
}
@Html.CheckBoxList("Cities", dataList, putCheckBoxesIntoTable)
@{ var disabledValues = new[] {"1", "4"}; }
@Html.CheckBoxList("Cities", dataList, null, disabledValues)
@{ var checkBoxHtmlAttributes = new { @class = "checkbox_class" }; }
@Html.CheckBoxList("Cities", dataList, checkBoxHtmlAttributes,
putCheckBoxesIntoTable, disabledValues, Position.Vertical)
Possible plans and modifications
- Add RadioButtonList and DropDownList support, and possibly, other kinds of lists!
Create NuGet package for this extension
Create MvcCheckBoxList.dll file with extension for easier distribution
Add annotations to functions so they will have more details in visual studio autocomplete box
Remove dependency on 'SelectListItem' system class (no dependency, if you would use strongly typed approach, however it is still there, if need to use older, view model independent approach)
Add advanced sorting options (I decided not to complicate things further, since all kinds of sorting can be easily done like that: YOUR_DATA_LIST.OrderBy(x => x.SOME_VALUE) via LINQ)
Cleaning up overload functions (done!)
History
- v.1.4.2.3
-
Fixed a bug where it requires MVC4 dependency (System.Web.WebPages 2.0.0.0), and doesn't work in MVC3 projects...
- v.1.4.2.2
- NuGet package added!
-
Additional parameter for both 'CheckBoxList' and 'CheckBoxListFor' - 'htmlAttributesExpr'
allows to pass custom html tags from database to be applied to each individual checkbox
(see good exaple of this in sample MVC3 project)
- Improved name generation
- Numerous other small fixes...
- v.1.3c
- Some minor bug fixes done
-
Created a sample MVC3 .NET 4.0 site which comes along
with this control, so you can test it first hand!
- v.1.3b
-
Added function annotations, some code cleanup
- v.1.3a
-
Instead of plain checkbox name it now creates a label linked to checkbox,
so you can also click on the label to select that checkbox!
Many thanks to
william0565 for idea
!
- v.1.3
-
'CheckBoxListFor' now generates full name from a lambda expression:
e.g.:
@Html.CheckBoxListFor(model => model.SomeClass.SubClass .... )
will create a list of checkboxes with 'name="SomeClass.SubClass"',
where older version would create only 'name="SubClass"'
- v.1.2
- You can now create strongly typed checkbox list from your view model!
- Added new method 'CheckBoxListFor' to be used with strongly typed approach
- v.1.1
-
Added new option 'HtmlTag.vertical_columns', which allows checkboxes to be arranged inside 4 vertically sorted floating sections
- Overload functions cleanup
- Overall code cleanup
- v.1.0
Regards