Created
June 21, 2012 10:56
-
-
Save danielrbradley/2965119 to your computer and use it in GitHub Desktop.
ASP.NET MVC Enumeration Dropdown Extensions
This file contains hidden or 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.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Text.RegularExpressions; | |
using System.Web.Mvc; | |
using System.Web.Mvc.Html; | |
namespace System.Web.Mvc.Html | |
{ | |
public static class EnumDropdownExtenstions | |
{ | |
/// <summary> | |
/// Returns an HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </summary> | |
/// <typeparam name="TModel">The type of the model.</typeparam> | |
/// <typeparam name="TProperty">The type of the value.</typeparam> | |
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param> | |
/// <param name="expression"> | |
/// An expression that identifies the object that contains the properties to | |
/// display. | |
/// </param> | |
/// <returns> | |
/// An HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The expression is not an enumeration type. | |
/// </exception> | |
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) | |
{ | |
return htmlHelper.EnumDropDownListFor(expression, value => | |
{ | |
return Regex.Replace( | |
Regex.Replace( | |
value.ToString(), | |
@"[a-z][A-Z]+", | |
m => string.Concat(m.Value[0], ' ', m.Value.Substring(1))), | |
@"[A-Z]{2,}[a-z]", | |
m => string.Concat(m.Value.Substring(0, m.Length - 2), ' ', m.Value.Substring(m.Length - 2))); | |
}); | |
} | |
/// <summary> | |
/// Returns an HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </summary> | |
/// <typeparam name="TModel">The type of the model.</typeparam> | |
/// <typeparam name="TProperty">The type of the value.</typeparam> | |
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param> | |
/// <param name="expression"> | |
/// An expression that identifies the object that contains the properties to | |
/// display. | |
/// </param> | |
/// <param name="displayValue"> | |
/// A function to convert an enumeration value into a readable name. | |
/// </param> | |
/// <returns> | |
/// An HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The expression is not an enumeration type. | |
/// </exception> | |
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Func<TProperty, string> displayValue) | |
{ | |
return htmlHelper.EnumDropDownListFor(expression, displayValue, null, null); | |
} | |
/// <summary> | |
/// Returns an HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </summary> | |
/// <typeparam name="TModel">The type of the model.</typeparam> | |
/// <typeparam name="TProperty">The type of the value.</typeparam> | |
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param> | |
/// <param name="expression"> | |
/// An expression that identifies the object that contains the properties to | |
/// display. | |
/// </param> | |
/// <param name="displayValue"> | |
/// A function to convert an enumeration value into a readable name. | |
/// </param> | |
/// <returns> | |
/// An HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The expression is not an enumeration type. | |
/// </exception> | |
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Func<TProperty, string> displayValue, object htmlAttributes) | |
{ | |
return htmlHelper.EnumDropDownListFor(expression, displayValue, null, htmlAttributes); | |
} | |
/// <summary> | |
/// Returns an HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </summary> | |
/// <typeparam name="TModel">The type of the model.</typeparam> | |
/// <typeparam name="TProperty">The type of the value.</typeparam> | |
/// <param name="htmlHelper">The HTML helper instance that this method extends.</param> | |
/// <param name="expression"> | |
/// An expression that identifies the object that contains the properties to | |
/// display. | |
/// </param> | |
/// <param name="displayValue"> | |
/// A function to convert an enumeration value into a readable name. | |
/// </param> | |
/// <returns> | |
/// An HTML select element for the property specified by the | |
/// expression, presenting the values with custom readable names. | |
/// </returns> | |
/// <exception cref="System.ArgumentException"> | |
/// The expression is not an enumeration type. | |
/// </exception> | |
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Func<TProperty, string> displayValue, string optionLabel, object htmlAttributes) | |
{ | |
Type enumType; | |
bool isOptional; | |
var propertyType = typeof(TProperty); | |
if (propertyType.IsEnum) | |
{ | |
enumType = propertyType; | |
isOptional = false; | |
} | |
else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && propertyType.GetGenericArguments().Single().IsEnum) | |
{ | |
enumType = propertyType.GetGenericArguments().Single(); | |
isOptional = true; | |
} | |
else | |
throw new ArgumentException("property is not an enumeration type.", "expression"); | |
var selected = expression.Compile().Invoke(htmlHelper.ViewData.Model); | |
var selectList = Enum.GetValues(enumType).Cast<TProperty>().OrderBy(p => p.ToString()).Select(p => new SelectListItem { Value = p.ToString(), Text = displayValue(p), Selected = p.Equals(selected) }).ToList(); | |
if (isOptional) | |
selectList.Insert(0, new SelectListItem { Value = string.Empty, Text = string.Empty, Selected = selected.Equals(null) }); | |
return htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); | |
} | |
} | |
} |
Great!
But it would be nice could if you could use the Display(Name = ...) attribute on enums. But that can be fixed when passing this as a function for displayValue:
I use: e => e.DisplayName() as parameter for the displayValue.
And created an extension method to the enum:
public static class EnumExtensions
{
public static string DisplayName(this Enum value)
{
Type enumType = value.GetType();
var enumValue = Enum.GetName(enumType, value);
MemberInfo member = enumType.GetMember(enumValue)[0];
var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
var outString = ((DisplayAttribute)attrs[0]).Name; //TODO Null check
if (((DisplayAttribute)attrs[0]).ResourceType != null)
{
outString = ((DisplayAttribute)attrs[0]).GetName();
}
return outString;
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I implement Globalization!