CheckBoxList(For)


What is it?

It is a custom extension of Microsoft MVC Framework's HtmlHelper class, which creates a postable Model-based list of check boxes.

It was created because there is no built-in MVC way to do this at all (including MVC4).


Features:
See it in action:
  @Html.CheckBoxListFor(model => model.CheckBoxListName,
                        model => model.ListOfYourData,
                        entity => entity.FieldToUseAsCheckBoxValue,
                        entity => entity.FieldToUseAsCheckBoxName,
                        model => model.ListOfYourSelectedData)
  
             
  selection to controller See More Examples

Install it

PM> Install-Package MvcCheckBoxList

Source it

Download Source .zip
< >
Fork me on GitHub

Learn it

See More Examples Read Documentation

Discuss it

Extension's Article on CodeProject.com

Examples

Given we have...

Base class City
public class City {
  public int Id { get; set; }           // Integer value of a checkbox
  public string Name { get; set; }      // String name of a checkbox
  public object Tags { get; set; }      // Object of html tags to be applied to checkbox, e.g.: 'new { tagName = "tagValue" }'
  public bool IsSelected { get; set; }  // Boolean value to select a checkbox on the list
}
And we use CitiesViewModel view model on our view
public class CitiesViewModel {
  public IList<City> AvailableCities { get; set; }
  public IList<City> SelectedCities { get; set; }
  public PostedCities PostedCities { get; set; }
}

// Helper class to make posting back selected values easier
public class PostedCities {
  public string[] CityIDs { get; set; }
}
And our controller accepts class PostedCities
public ActionResult Examples(PostedCities postedCities) {
  return View(/* Create View Model */);
}

We can use examples below to create our checkbox list:

Base example
             
@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,  // checkbox list name, 'PostedCities.CityIDs' in this case
                      x => x.AvailableCities,       // List<City>()
                      x => x.Id,                    // City.Id
                      x => x.Name,                  // City.Name
                      x => x.SelectedCities)        // List<City>() - should contain only cities to be selected
Base example (boolean selector)
             
@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,  // Checkbox list name, 'PostedCities.CityIDs' in this case
                      x => x.AvailableCities,       // List<City>()
                      x => x.Id,                    // City.Id
                      x => x.Name,                  // City.Name
                      x => x.IsSelected)            // City.IsSelected - boolean property in the database
@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,        // Checkbox list name, 'PostedCities.CityIDs' in this case
                      x => x.AvailableCities,             // List<City>()
                      x => x.Id,                          // City.Id
                      x => x.Name,                        // City.Name
                      x => selectedIds.Contains(x.Id))    // Linq query returns bool if item Id matches the list
Vertical Checkbox List







@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,
                      x => x.AvailableCities,          
                      x => x.Id,               
                      x => x.Name,               
                      x => x.SelectedCities,
                      Position.Vertical)
Custom HTML tags for individual checkboxes from Model (Database)


Some cities will have custom tags from database: ('new {what = "smallCity"}' for Monroe, and 'new {what = "bigCity"}' for Moscow)
             


We have this jquery code which will apply to certain custom tags from db:
$('[what="smallCity"]').css("color", "blue");
$('[what="bigCity"]').css("color", "green");
And we call the control like this:
@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,
                      x => x.AvailableCities,
                      x => x.Id,
                      x => x.Name,
                      x => x.SelectedCities,
                      x => x.Tags)            // Tags is a database/model field of type 'object'
                                              // with value similar to: 'new {tagName = "tagValue"}'
                                              // they will be merged with other tags and applied to checkbox and its label
Display templates to render html for checkbox







First you need to create Views\Shared\DisplayTemplates\City.cshtml file to hold a template for our base class City. It must have same name as class City for which it templates, and must have a @model set to use City (including applicable namespace).
@model MvcCheckBoxListSampleApp.Model.City
<strong>@Model.Name</strong> - text from display template
var htmlListInfo = new HtmlListInfo(HtmlTag.vertical_columns, 2, null, TextLayout.Default, TemplateIsUsed.Yes);
@Html.CheckBoxListFor(model => model.PostedCities.CityIDs,
                      model => model.AvailableCities,
                      city => city.Id,
                      city => city.Name,
                      model => model.SelectedCities,
                      htmlListInfo)
Full Example









We have this style for each checkbox:
.styled_checkbox {
  background: wheat; cursor:pointer; border-radius:5px;
  margin: 3px; padding: 0px 5px;
}
Also we have this style for the list wrapper (applies to each column):
.styled_list {
  color:green; background:lightblue; border-radius:5px;
  margin-right: 15px; padding:3px 5px 3px 5px; line-height: 25px;
}
And we apply them below:
@{
  var htmlListInfo = new HtmlListInfo(HtmlTag.vertical_columns, 2, new { @class="styled_list" };
  @Html.CheckBoxListFor(x => x.PostedCities.CityIDs,
                        x => x.AvailableCities,
                        x => x.Id,
                        x => x.Name,
                        x => x.SelectedCities,
                        new { @class="styled_checkbox" },      // additional html attributes (for each checkbox and label)
                        htmlListInfo),                         // formatting
                        new[] {"3", "5", "7"},                 // disabled values
                        x => x.Tags)                           // html tags from database
}
Right-to-left Checkbox/Label direction (e.g. for Arabic, Hebrew and other right-to-left languages)







@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,
                      x => x.AvailableCities,          
                      x => x.Id,               
                      x => x.Name,               
                      x => x.SelectedCities,
                      Position.Vertical_RightToLeft)
@Html.CheckBoxListFor(x => x.PostedCities.CityIDs,
                      x => x.AvailableCities,          
                      x => x.Id,               
                      x => x.Name,               
                      x => x.SelectedCities,
                      new HtmlListInfo(HtmlTag.vertical_columns, 0, null, TextLayout.RightToLeft))

Documentation

Given we have...

Base class City
public class City {
  public int Id { get; set; }           // Integer value of a checkbox
  public string Name { get; set; }      // String name of a checkbox
  public object Tags { get; set; }      // Object of html tags to be applied to checkbox, e.g.: 'new { tagName = "tagValue" }'
  public bool IsSelected { get; set; }  // Boolean value to select a checkbox on the list
}
And we use CitiesViewModel view model on our view
public class CitiesViewModel {
  public IList<City> AvailableCities { get; set; }
  public IList<City> SelectedCities { get; set; }
  public PostedCities PostedCities { get; set; }
}
// Helper class to make posting back selected values easier
public class PostedCities {
  public string[] CityIDs { get; set; }
}
And our controller accepts class PostedCities
public ActionResult Examples(PostedCities postedCities) {
  return View(/* Create View Model */);
}
Base overloads
Base checkbox list call structure:
@Html.CheckBoxList("LIST_NAME", 
                   model => model.LIST_DATA, 
                   entity => entity.VALUE, 
                   entity => entity.NAME, 
                   model => model.SELECTED_VALUES)
                   // or entity => entity.IS_CHECKED
OR
@Html.CheckBoxListFor(model => model.LIST_NAME, 
                      model => model.LIST_DATA, 
                      entity => entity.VALUE, 
                      entity => entity.NAME, 
                      model => model.SELECTED_VALUES)
                      // or entity => entity.IS_CHECKED
And in our example it looks like this:
@Html.CheckBoxListFor(model => model.PostedCities.CityIDs, 
                      model => model.AvailableCities, 
                      entity => entity.Id, 
                      entity => entity.Name, 
                      model => model.SelectedCities)
Or if using boolean selector:
@Html.CheckBoxListFor(model => model.PostedCities.CityIDs, 
                      model => model.AvailableCities, 
                      entity => entity.Id, 
                      entity => entity.Name, 
                      entity => entity.IsSelected)
where entity.IsSelected is a boolean value from database
And another way to use boolean selector:
If we have a list of selected values on our View - var selectedIds = new List<int> { 1, 3, 5 }; it'll look like this:
@Html.CheckBoxListFor(model => model.PostedCities.CityIDs, 
                      model => model.AvailableCities, 
                      entity => entity.Id, 
                      entity => entity.Name, 
                      entity => selectedIds.Contains(entity.Id))
where selectedIds.Contains(entity.Id) returns bool if item Id matches the list
Basic Settings
Since five base properties don't change, only extra ones will be shown, so placeholder ... means usage of five base properties
You might need to add this reference to your view first (namespace for Position enum and others):
@using MvcCheckBoxList.Model
1. Set position (direction) of the list:
@Html.CheckBoxListFor( ... , Position.Horizontal)
Position Can be Position.Horizontal, Position.Vertical, Position.Horizontal_RightToLeft, or Position.Vertical_RightToLeft where last two are to reverse checkbox and label for right-to-left languages
2. Set html attributes for both checkbox and label:
@Html.CheckBoxListFor( ... , x => new { @class="class_name" }) // Tags will be applied to all checkbox/label combos
or get Tags object from database:
@Html.CheckBoxListFor( ... , x => x.Tags) // x.Tags will be applied only to particular checkbox/label combo
3. Set html attributes and position:
@Html.CheckBoxListFor( ... , Position.Horizontal, x => new { @class="class_name" })
4. Set html attributes for all, disabled values, position, and individual html attributes (all attributes will be merged together):
@Html.CheckBoxListFor( ... , x => new { @class="class_name" }, new[] {"3", "5", "7"}, Position.Horizontal, x => x.Tags)
Advanced Settings
You might need to add this reference to your view first (namespace for HtmlListInfo class and others):
@using MvcCheckBoxList.Model
1. Set custom layout using HtmlListInfo class:
var htmlListInfo = new HtmlListInfo(HtmlTag.table, 2, new { @class="class_name" }, TextLayout.Default, TemplateIsUsed.Yes);
@Html.CheckBoxListFor( ... , htmlListInfo)
There, in HtmlListInfo class, HtmlTag can be HtmlTag.table or HtmlTag.vertical_columns; 2 is a number of columns;
TextLayout can be TextLayout.Default or TextLayout.RightToLeft (for right to left languages)
2. Set layout with HtmlListInfo class and set html attributes:
@Html.CheckBoxListFor( ... , htmlListInfo, x => new { tagName = "tagValue" })  // Tags will be applied to all checkbox/label combos
or get Tags object from database:
@Html.CheckBoxListFor( ... , htmlListInfo, x => x.Tags })  // x.Tags will be applied only to particular checkbox/label combo
3. Set html attributes for all, set layout with HtmlListInfo, set disabled values, and individual html attributes (all attributes will be merged together):
@Html.CheckBoxListFor( ... , new { @class="class_name" }, htmlListInfo, new[] {"3", "5", "7"}, x => x.Tags)
There, x.Tags is a value of type object and should be equal to something similar to this new { tag1 = "value1", tag2="value2" } and represent one or more custom html attributes, and will be applied to both checkbox and label
Also note that x.Tags is an optional parameter for each available overload. Just add it as a last parameter to @Html.CheckBoxListFor( ... , x => x.Tags) checkbox list call

For more information and discussion see

Contributors