C# MVC Bootstrap Check Box List

This is my solution for a check box list in MVC with Bootstrap

Posted on July 27, 2017 9:23AM

I have a client I am currently working with that loves using check box lists. Without having to write a lot of code, I came up with an easy way to do checkbox lists in MVC.

Backend Code

    public class MyViewModel
    {
        public int[] SelectedItems { get; set; }

        public List ItemsToSelect => new List
        {
            new SelectListItem {Text = "A", Value = "1"},
            new SelectListItem {Text = "B", Value = "2"},
            new SelectListItem {Text = "C", Value = "3"},
            new SelectListItem {Text = "D", Value = "4"},
            new SelectListItem {Text = "E", Value = "5"},
            new SelectListItem {Text = "F", Value = "6"},
            new SelectListItem {Text = "G", Value = "7"},
            new SelectListItem {Text = "H", Value = "8"},
            new SelectListItem {Text = "I", Value = "9"},
            new SelectListItem {Text = "J", Value = "10"},
            new SelectListItem {Text = "K", Value = "11"},
            new SelectListItem {Text = "L", Value = "12"},
            new SelectListItem {Text = "M", Value = "13"},
            new SelectListItem {Text = "N", Value = "14"},
            new SelectListItem {Text = "O", Value = "15"},
            new SelectListItem {Text = "P", Value = "16"}
        };
    }

    public static class HTMLHelperExtensions
    {
        public static MvcHtmlString CheckBoxListForBootstrap<TModel, TProperty>(this HtmlHelper<TModel> helper,
            Expression<Func<TModel, IEnumerable<TProperty>>> expression, IEnumerable<SelectListItem> items,
            int columns = 1)
        {
            var modelMetadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            var propertyName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(modelMetadata.PropertyName);
            var list = expression.Compile().Invoke(helper.ViewData.Model);
            var selectedValues = new List<string>();
            if (list != null)
                selectedValues = new List<TProperty>(list).ConvertAll(i => i.ToString());
            var sb = new StringBuilder();
            sb.AppendLine($"<div style=\"columns:{columns}\">");
            var x = 0;
            foreach (var item in items)
                sb.AppendLine(
                    $"<div class=\"checkbox\"><label><input type=\"checkbox\" id=\"{TagBuilder.CreateSanitizedId(propertyName)}{x++}\" name=\"{propertyName}\" value=\"{item.Value}\"{(selectedValues.Contains(item.Value) ? " checked=checked" : "")} /> {item.Text}</label></div>");
            sb.AppendLine("</div><br/>");
            return MvcHtmlString.Create(sb.ToString());
        }
    }

    public class TestController : Controller
    {
        [Route("Test")]
        [HttpGet]
        public ActionResult Test()
        {
            return View(new MyViewModel());
        }

        [Route("Test")]
        [HttpPost]
        public ActionResult Test(MyViewModel model)
        {
            return View(model);
        }

View

@using Website.Models
@model MyViewModel
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Test</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container"> <form method="post"> <h2>Single List</h2> @Html.CheckBoxListForBootstrap(m => m.SelectedItems, Model.ItemsToSelect) <h2>Two Column List</h2> @Html.CheckBoxListForBootstrap(m => m.SelectedItems, Model.ItemsToSelect, 2) <h2>Three Column List</h2> @Html.CheckBoxListForBootstrap(m => m.SelectedItems, Model.ItemsToSelect, 3) </form> </div> </body> </html>

Result

Single List


Two Column List


Three Column List