Wednesday, June 17, 2015

Modify LabelFor to display an * for required fields

We are going to create a html helper method in MVC to automatically show an * for required fields.


Create a class let say ReqLabel

using System;
using System.Linq;
using System.Web.Mvc;
using System.Linq.Expressions;
using System.ComponentModel;

namespace YourNameSpace.Models
{
public static class ReqLabel
{
    public static MvcHtmlString ReqLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();

        if (metaData.IsRequired)
            labelText += "*";

        if (String.IsNullOrEmpty(labelText))
            return MvcHtmlString.Empty;

        var label = new TagBuilder("label");
        label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(htmlAttributes))
        {
            label.MergeAttribute(prop.Name.Replace('_', '-'), prop.GetValue(htmlAttributes).ToString(), true);
        }

        label.InnerHtml = labelText;
        return MvcHtmlString.Create(label.ToString());
    }

}
}

don't forget at add name of your name space to your class


Now you can use this new helper method inside your views as follows

include the namespace in your view

@using YourNameSpace.Models



and use ReqLabelFor instead of LabelFor

@Html.ReqLabelFor(model => model.Category, new { @class = "control-label col-md-3" })