10

Im using a snippet of code from another stackoverflow question:

namespace MvcHtmlHelpers
{
    public static class htmlHelpers
    {
        /// <summary>
        /// Radio button for : Adapted to support enum labels from display attributes
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression
        )
        {
            var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            var names = Enum.GetNames(metaData.ModelType);
            var sb = new StringBuilder();
            foreach (var name in names)
            {
                var id = string.Format(
                    "{0}_{1}_{2}",
                    htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix,
                    metaData.PropertyName,
                    name
                );

                var radio =  htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();
                sb.AppendFormat(
                    "<label for=\"{0}\">{1}</label> {2}",
                    id,
                    HttpUtility.HtmlEncode(name),
                    radio
                );
            }
            return MvcHtmlString.Create(sb.ToString());
        }
    }
}

Along side my current enum:

public enum Options
    {
       [Display(Name ="Yes")]
        0,
       [Display(Name = "No")]
        1,
      [Display(Name = "Other")]
        2,
    }

If I then use @html.RadioButtonForEnum(...) It displays my enums with the appropriate box selected no problem. However, I want them to use the label value [Display(Name = "<text>")] so they make more sense! - i.e. not just 0,1,2.

3 Answers 3

12

You could use reflection to fetch the value:

public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression
)
{
    var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

    var sb = new StringBuilder();
    var enumType = metaData.ModelType;
    foreach (var field in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
    {
        var value = (int)field.GetValue(null);
        var name = Enum.GetName(enumType, value);
        var label = name;
        foreach (DisplayAttribute currAttr in field.GetCustomAttributes(typeof(DisplayAttribute), true))
        {
            label = currAttr.Name;
            break;
        }

        var id = string.Format(
            "{0}_{1}_{2}",
            htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix,
            metaData.PropertyName,
            name
        );
        var radio = htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();
        sb.AppendFormat(
            "<label for=\"{0}\">{1}</label> {2}",
            id,
            HttpUtility.HtmlEncode(label),
            radio
        );
    }
    return MvcHtmlString.Create(sb.ToString());
}
Sign up to request clarification or add additional context in comments.

3 Comments

This works a treat, unfortunately I'm not getting an auto selected value anymore though: @Html.RadioButtonForEnum(m => m.Options)
@RawryLions, right, I have updated my answer to fix this. It should work now as expected.
fantastic stuff, thanks for the help. I can now use this as a basis to create enum to other form elements too :)
0

You probably need an extension method for your enum to get the display attribute that you put on your enum options. Then when you get the name or value of your options enum value in the RadioButtonForEnum method you would just call the extensions method to fill up the value.

I recently wrote a blog post about this topic: http://joerijans.blogspot.com/2011/10/triple-door-extension-method-custom.html

Hope this helps.

Comments

0

I use [Description] in my code, but you can simply change that to use DisplayAttribute:

https://gist.github.com/1287511

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.