UC Davis College of Agricultural & Environmental Sciences
Personal tools

Extend MVC LabelFor Method

by Jason Sylvestre — last modified Nov 17, 2010 09:47 AM

The LabelFor method provides strongly typed labels using lambda expressions. Unfortunately, the default MVC one doesn't provide a way to add extra attributes and if you don't want the text from the field variable you have to use the DisplayNames data annotations. The method here uses the variable name or data annotation DisplayName, but allows the Camel Case variable to be split into words, add a colon to the end, add extra text, and/or specify an id value for the label.

Note, the "Inflector.Titleize(labelText)" is a UCDArch method to convert Camel case to titleized (first letter capitalized of each word) strings.

Usages:

<%= Html.LabelFor(a => a.Ticket.MessageBody, DisplayOptions.HumanizeAndColon) %>
<%= Html.LabelFor(a => a.Ticket.MessageBody, DisplayOptions.HumanizeAndColon extraText: " (Email Body)") %>
<%= Html.LabelFor(a => a.Ticket.MessageBody, DisplayOptions.HumanizeAndColon, extraText: " (Email Body)", generatedId:true) %>
<%= Html.LabelFor(a => a.Ticket.MessageBody, DisplayOptions.HumanizeAndColon, extraText: " (Email Body)", id: "MyLabelId") %>

Code:

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using UCDArch.Core.Utils;
 
namespace HelpRequest.Controllers.Helpers
{
 
    public static class LabelExtensions
    {
        public static MvcHtmlString Label(this HtmlHelper html, string expression, string id = "", bool generatedId = false)
        {
            return LabelHelper(html,
                               ModelMetadata.FromStringExpression(expression, html.ViewData),
                               expression, DisplayOptions.None, "", id, generatedId);
        }
 
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
        public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, DisplayOptions displayOptions, string extraText = "", string id = "", bool generatedId = false)
        {
            return LabelHelper(html,
                               ModelMetadata.FromLambdaExpression(expression, html.ViewData),
                               ExpressionHelper.GetExpressionText(expression), displayOptions, extraText, id, generatedId);
        }
 
        //public static MvcHtmlString LabelForModel(this HtmlHelper html)
        //{
        //    return LabelHelper(html, html.ViewData.ModelMetadata, String.Empty);
        //}
 
        internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, DisplayOptions displayOptions, string extraText, string id, bool generatedId)
        {
            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
            if (String.IsNullOrEmpty(labelText))
            {
                return MvcHtmlString.Empty;
            }
            var sb = new StringBuilder();
            if (displayOptions == DisplayOptions.Humanize || displayOptions == DisplayOptions.HumanizeAndColon)
            {
                sb.Append(Inflector.Titleize(labelText));
            }
            else
            {
                sb.Append(labelText);
            }
            sb.Append(extraText);
            if (displayOptions == DisplayOptions.HumanizeAndColon && labelText.Substring(labelText.Length - 1) != ":")
            {
                sb.Append(":");
            }
 
            var tag = new TagBuilder("label");
            if (!string.IsNullOrWhiteSpace(id))
            {
                tag.Attributes.Add("id", id);
            }
            else if (generatedId)
            {
                tag.Attributes.Add("id", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName) + "_Label");    
            }
            
            tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
            tag.SetInnerText(sb.ToString());
 
            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }
 
        
    }
    public enum DisplayOptions
    {
        Humanize,
        HumanizeAndColon,
        None
    }
}

 

TagBuilder class?

Posted by Anonymous User at Feb 01, 2011 09:19 AM
What is the TabBuilder class? Is that another internal UC David utility?