September 20 2012

MVC CheckboxList for property of type IList<Enum>

This is an extension method for creating a checkbox list for a list of enum values (IList<Enum>).

It's a modified version of the CheckboxListForEnum extension method I found on the Xango project. Their version creates a checkbox list for a property that contains a single enum value.

public static MvcHtmlString CheckboxListForEnumList(
    this HtmlHelper html,
    Expression> expression,
    IDictionary htmlAttributes = null)
{
    var enumType = (typeof(TProperty)).GetProperties()[0].PropertyType;

    if (!enumType.IsEnum)
        throw new ArgumentException("TProperty must be a list of enumerated types");

    TProperty value = expression.Compile()((TModel)html.ViewContext.ViewData.Model);

    var items = Enum
        .GetValues(enumType)
        .Cast()
        .Select(c => new SelectListItem
        {
            Text = c.ToString(),
            Value = c.ToString(),
            Selected = value != null && ((IList)value).Contains(c)
        });

    var name = ExpressionHelper.GetExpressionText(expression);

    var sb = new StringBuilder();
    var ul = new TagBuilder("ul");

    ul.MergeAttributes(htmlAttributes);

    foreach (var item in items)
    {
        var id = string.Format("{0}_{1}", name, item.Value);

        var li = new TagBuilder("li");

        var checkBox = new TagBuilder("input");
        checkBox.Attributes.Add("id", id);
        checkBox.Attributes.Add("value", item.Value);
        checkBox.Attributes.Add("name", name);
        checkBox.Attributes.Add("type", "checkbox");
        if (item.Selected)
            checkBox.Attributes.Add("checked", "checked");

        var label = new TagBuilder("label");
        label.Attributes.Add("for", id);

        label.SetInnerText(item.Text);

        li.InnerHtml = checkBox.ToString(TagRenderMode.SelfClosing) + "\r\n" +
                        label.ToString(TagRenderMode.Normal);

        sb.AppendLine(li.ToString(TagRenderMode.Normal));
    }

    ul.InnerHtml = sb.ToString();

    return new MvcHtmlString(ul.ToString(TagRenderMode.Normal));
}

Sponsored by