Last active
August 3, 2017 16:35
-
-
Save naepalm/dda077609e639f53d7b2b83076cc1a0b to your computer and use it in GitHub Desktop.
The handy CheckboxListFor Html extension.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using(Html.BeginUmbracoForm<ExampleSurfaceController>("SubmitForm", FormMethod.Post)) | |
{ | |
@Html.CheckBoxListFor(x => x.CheckboxListField, Model.CheckboxListSelectItems) | |
<button type="submit">Submit</button> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web.Mvc; | |
namespace Client.Web.Models | |
{ | |
public class ExampleModel | |
{ | |
// This is the field the checkbox list is submitted to with string values | |
public List<string> CheckboxListField { get; set; } | |
// This populates the checkbox list items that display on the form | |
public SelectList CheckboxListSelectItems | |
{ | |
get | |
{ | |
return new SelectList(new[,] { { "Item 1", "Item 2", "Item 3" }}); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Web.Mvc; | |
using System.Web.Routing; | |
using Umbraco.Core; | |
namespace Client.Web.Extensions | |
{ | |
public static class HtmlHelperExtensions | |
{ | |
/// <summary> | |
/// Creates a checkbox list for an Enum property | |
/// </summary> | |
public static MvcHtmlString EnumCheckBoxListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TEnum>>> expression, object htmlAttributes = null) | |
{ | |
return html.CheckBoxListFor(expression, GetEnumSelectList<TEnum>(), htmlAttributes); | |
} | |
/// <summary> | |
/// Returns a checkbox for each of the provided <paramref name="items"/>. | |
/// </summary> | |
public static MvcHtmlString CheckBoxListFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, IEnumerable<SelectListItem> items, object htmlAttributes = null) | |
{ | |
var listName = ExpressionHelper.GetExpressionText(expression); | |
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); | |
items = GetCheckboxListWithDefaultValues(metaData.Model, items); | |
return htmlHelper.CheckBoxList(listName, items, htmlAttributes); | |
} | |
/// <summary> | |
/// Returns a checkbox for each of the provided <paramref name="items"/>. | |
/// </summary> | |
public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string listName, IEnumerable<SelectListItem> items, object htmlAttributes = null) | |
{ | |
var container = new TagBuilder("div"); | |
foreach (var item in items) | |
{ | |
var label = new TagBuilder("label"); | |
label.MergeAttribute("class", "checkbox"); // default class | |
label.MergeAttributes(new RouteValueDictionary(htmlAttributes), true); | |
var cb = new TagBuilder("input"); | |
cb.MergeAttribute("type", "checkbox"); | |
cb.MergeAttribute("name", listName); | |
cb.MergeAttribute("value", item.Value ?? item.Text); | |
if (item.Selected) | |
cb.MergeAttribute("checked", "checked"); | |
label.InnerHtml = cb.ToString(TagRenderMode.SelfClosing) + item.Text; | |
container.InnerHtml += label.ToString(); | |
} | |
return new MvcHtmlString(container.ToString()); | |
} | |
private static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(bool addEmptyItemForNullable = false, string emptyItemText = "", string emptyItemValue = "") | |
{ | |
var enumType = typeof(TEnum); | |
var nullable = false; | |
if (!enumType.IsEnum) | |
{ | |
enumType = Nullable.GetUnderlyingType(enumType); | |
if (enumType != null && enumType.IsEnum) | |
{ | |
nullable = true; | |
} | |
else | |
{ | |
throw new ArgumentException("Not a valid Enum type"); | |
} | |
} | |
var selectListItems = (from v in Enum.GetValues(enumType).Cast<TEnum>() | |
select new SelectListItem | |
{ | |
Text = v.ToString().SeparatePascalCase(), | |
Value = v.ToString() | |
}).ToList(); | |
if (nullable && addEmptyItemForNullable) | |
{ | |
selectListItems.Insert(0, new SelectListItem { Text = emptyItemText, Value = emptyItemValue }); | |
} | |
return selectListItems; | |
} | |
private static IEnumerable<SelectListItem> GetCheckboxListWithDefaultValues(object defaultValues, IEnumerable<SelectListItem> selectList) | |
{ | |
var defaultValuesList = defaultValues as IEnumerable; | |
if (defaultValuesList == null) | |
return selectList; | |
IEnumerable<string> values = from object value in defaultValuesList | |
select Convert.ToString(value, CultureInfo.CurrentCulture); | |
var selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase); | |
var newSelectList = new List<SelectListItem>(); | |
selectList.ForEach(item => | |
{ | |
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text); | |
newSelectList.Add(item); | |
}); | |
return newSelectList; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Text.RegularExpressions; | |
namespace Client.Web.Extensions | |
{ | |
public static class StringExtensions | |
{ | |
/// <summary> | |
/// Separates a PascalCase string | |
/// </summary> | |
/// <example> | |
/// "ThisIsPascalCase".SeparatePascalCase(); // returns "This Is Pascal Case" | |
/// </example> | |
/// <param name="value">The value to split</param> | |
/// <returns>The original string separated on each uppercase character.</returns> | |
public static string SeparatePascalCase(this string value) | |
{ | |
return Regex.Replace(value, "([A-Z])", " $1").Trim(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment