DropDownListFor for enum with custom values (stored in attributes) doesn't select item

1.1k views Asked by At

I have enum with assigned string values (in attributes) and would like to have html helper for displaying it. Unfortunately I need to use assigned values as a keys in ddl. Because of that it doesn't select item stored in ViewModel. What to do?

Sample Enum

public enum StatusEnum
{
    [Value("AA")]
    Active,

    [Value("BB")]
    Disabled
}

ViewModel

public class UserViewModel
{
    public StatusEnum Status { get; set; }
}

View

@Html.DropDownListForEnum(x => x.Status, new {})

DropDownListForEnum helper

public static MvcHtmlString DropDownListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

    IEnumerable<SelectListItem> items = Enum.GetNames(typeof(TEnum))
                                            .Select(n => (TEnum)Enum.Parse(typeof(TEnum), n))
                                            .Select(e => new SelectListItem() {
                                                Text = e.ToString(),
                                                Value = EnumExtension.GetValue(e).ToString(),
                                                Selected = EnumExtension.GetValue(e) == EnumExtension.GetValue(metadata.Model)
                                            })
                                            .ToList();

    return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
1

There are 1 answers

1
Davor Zlotrg On

Instead of passing IEnumerable<SelectListItem> to the dropdown, create and populate SelectList manually and pass that and it will work:

public static MvcHtmlString DropDownListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

    var items = Enum.GetNames(typeof(TEnum))
                .Select(n => (TEnum)Enum.Parse(typeof(TEnum), n))
                .Select(e => new 
                {
                    Id = Convert.ToInt32(e),
                    Text = e.ToString(),
                    Value = EnumExtension.GetValue(e).ToString(),
                    Selected = EnumExtension.GetValue(e) == EnumExtension.GetValue(metadata.Model)
                })
                .ToList();

    var selectList = new SelectList(items, "Text", "Value", selectedValue: items.Find(i => i.Selected).Text);
    return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}