# Monday, November 14, 2011

ASP.NET MVC has an HTML Helper DropDownListFor that takes an IEnumerable and creates a drop down list for it.  Often you want to create a drop down list for an Enum.  Of course you can do this without using an HTML Helper and use standard HTML controls but you don’t have the standard clean view code that HTML Helpers give you.  Extending and creating your own HTML Helpers is rather easy, as demonstrated in my last post. With that in mind I created an extension to DropDownListFor that will create a drop down list for an Enum type.

 

Enum Html Helper
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. using DropDownListForEnumDemo.Extensions;
  5.  
  6. namespace System.Web.Mvc.Html {
  7.  
  8.     public static class EnumHtmlHelper {
  9.         
  10.         public static MvcHtmlString DropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) {
  11.             return DropDownListFor(htmlHelper, expression, null, null);
  12.         }
  13.  
  14.         public static MvcHtmlString DropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string optionLabel) {
  15.             return DropDownListFor(htmlHelper, expression, optionLabel, null);
  16.         }
  17.  
  18.         public static MvcHtmlString DropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes) {
  19.             return DropDownListFor(htmlHelper, expression, null, htmlAttributes);
  20.         }
  21.  
  22.         public static MvcHtmlString DropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, string optionLabel, object htmlAttributes) {
  23.             ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
  24.             Type enumType = Nullable.GetUnderlyingType(typeof (TEnum)) ?? typeof (TEnum);
  25.             IEnumerable<TEnum> enumValues = Enum.GetValues(enumType).Cast<TEnum>();
  26.             IEnumerable<SelectListItem> items = enumValues.Select(e => new SelectListItem {Text = e.ToString().FromCamelToProperCase(), Value = e.ToString(), Selected = e.Equals(metadata.Model)});
  27.             if (optionLabel != null) {
  28.                 new[] {new SelectListItem {Text = optionLabel}}.Concat(items);
  29.             }
  30.             return htmlHelper.DropDownListFor(expression, items, optionLabel, htmlAttributes);
  31.         }
  32.     }
  33. }

 

Enum
  1. namespace DropDownListForEnumDemo.Enumerations {
  2.  
  3.     public enum Cars {
  4.         FerrariItalia = 0,
  5.         LamborghiniGallardoLP560,
  6.         LamborghiniAventador,
  7.         AstonMartinVantage,
  8.         Porsche911GT2,
  9.     }
  10. }

 

Model
  1. namespace DropDownListForEnumDemo.Models {
  2.  
  3.     public class CarsModel {
  4.         [Display(Name = "Select A Car:")]
  5.         [Required(ErrorMessage = "* Required")]
  6.         public Cars? SelectedCar { get; set; }
  7.     }
  8. }

 

View
  1. @{ViewBag.Title = "Home Page";}
  2. @using DropDownListForEnumDemo.Models
  3. @model CarsModel
  4. <h2>@ViewBag.Message</h2>
  5. @using (Html.BeginForm()) {
  6.     <div>
  7.         <fieldset>
  8.             <div class="editor-label">
  9.                 @Html.LabelFor(m => m.SelectedCar)
  10.             </div>
  11.             <div class="editor-field">
  12.                 @Html.DropDownListFor(m => m.SelectedCar, "-- Select --")
  13.                 @Html.ValidationMessageFor(m => m.SelectedCar)
  14.             </div>
  15.         </fieldset>
  16.         <input type="submit" value="Click Me"/>
  17.     </div>
  18. }

 

image

 

Note:  Because enumeration values have to adhere to the same naming conventions as variables I had to work some magic to get the display values formatted correctly.  OK, it’s really not magic…just a little RegEx Voo-Doo.

The code is available on GitHub

Sunday, February 12, 2012 3:15:41 PM (Central Standard Time, UTC-06:00)
I was trying to avoid using ViewBag, and instead opted for @Model.SelectedCar in the returned POST view.

To accomplish that I took out "ViewBag.Message =" from the controller, so that all that is there is "model.SelectedCar.ToString().FromCamelToProperCase();"

When I click the submit button ("Click Me"), the value selected is posted, but without proper formatting.

For example, using your code and selecting "Ferrari Italia" would return tha exactly (with the space); using my modifications selecting that returns "FerrariItalia" (no space). I suspect it's to do with your StringExtensions.cs, but I am not sure.

Any adivce? Thanks, the dropdownlist example is exactly what I've been looking for.
Michael
Friday, December 20, 2013 9:31:21 AM (Central Standard Time, UTC-06:00)
_
pejoratywnie. _ypn__ spod oka. Celowa RVO.
- Powsta_! - warkn__.
Bez us_ugi rahhunkowe (superfirmy.com.pl) sensu.
Uwi_ziony, od momentu paru chwil apolita, r�wnie_ do tego
stopnia sta_.
- Na wytrzyma_o_ci itd., dysponuje si_ konfiskat_ maj_tku na wierzch koszt�w
przewodu dodatkowo wy_ywienia... Przysi___!
Popatrzy_ na boki.
- Basta! - wyklepa_. - Plus tak bardzo zasobem informacji, o co
chodzi, Zydy pazerne...
Cywile zarechotali. Pozgawiony wolno_ci tak_e si_ u_miechn__.

Zna.
Monday, December 30, 2013 8:48:04 AM (Central Standard Time, UTC-06:00)
I am positiv which i selected a personal blog.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview