Thursday, December 14, 2017

Automatically marking Required labels with (*) in ASP.NET MVC

 
Since you want to style the label text and the associated asterisk differently, then you cannot use the inbuilt LabelFor() method (the HtmlHelper methods encode the vale of the label text.
Instead you need to generate you own html in the method.
 If you want the asterisk in red but the text in black then you need to create 2 separate <span> elements within a <label> and style the asterisk.

using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
 
namespace RepositoryPatternPrac.InfraStructure.HtmlHelpers
{
    public static class LabelWithAstrickHelper
    {       
         public static MvcHtmlString LabelWithAstrick<TModelTValue>(this HtmlHelper<TModel> html,  
                                     Expression<Func<TModelTValue>> expression, object htmlAttributes)
        {
            var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            var name = ExpressionHelper.GetExpressionText(expression);
            string text = metadata.DisplayName ?? metadata.PropertyName ?? name.Split('.').Last();
            // Build 2 span elements containing text and the styled asterisk
            StringBuilder innerHtml = new StringBuilder();
            TagBuilder span = new TagBuilder("span");
            span.InnerHtml = text;
            innerHtml.Append(span.ToString());
            if (metadata.IsRequired)
            {
                span = new TagBuilder("span");
                span.InnerHtml = "*";
                span.MergeAttribute("style""color:red;"); // we can also use span.AddCssClass instead.
                innerHtml.Append(span.ToString());
            }
            // Create the label element and add the 2 span elements
            TagBuilder label = new TagBuilder("label");
            label.Attributes.Add("for"TagBuilder.CreateSanitizedId(html.ViewContext.ViewData
                                 .TemplateInfo.GetFullHtmlFieldName(name)));
            
            RouteValueDictionary attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
            label.MergeAttributes(attributes, replaceExisting: true);
            label.InnerHtml = innerHtml.ToString();
            return new MvcHtmlString(label.ToString());
        }
     }
}
 
 
Note that I hard-coded an inline style for the asterisk as per your 
code, however I would recommend you use a class name instead using span.AddCssClass("...."); 
and create a css definition for that class name to give you more flexibility. 

0 comments:

Post a Comment

Twitter Delicious Facebook Digg Stumbleupon Favorites More