Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can i change the way LabelFor render in MVC?

i would like to change the way LabelFor render. Can i do that with a DisplayTemplate?

LabelFor generate a label tag and i would like to add a ":" at the end of the label.

thank you!

alex

like image 373
Alexandre Jobin Avatar asked Dec 22 '22 01:12

Alexandre Jobin


2 Answers

Here is an HTML Helper that will do that:

public static class LabelExtensions {
    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    public static MvcHtmlString SmartLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
        return LabelHelper(html,
                           ModelMetadata.FromLambdaExpression(expression, html.ViewData),
                           ExpressionHelper.GetExpressionText(expression));
    }

    internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName) {
        string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
        if (String.IsNullOrEmpty(labelText)) {
            return MvcHtmlString.Empty;
        }

        // uncomment if want * for required field
        //if (metadata.IsRequired) labelText = labelText + " *";
        labelText = labelText + ":";

        TagBuilder tag = new TagBuilder("label");
        tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
        tag.SetInnerText(labelText);
        return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
    }
}

To use it:

<%:Html.SmartLabelFor(m => m.FirstName)%>

It will render:

<label for="FirstName">First Name:</label>

Or if you uncomment the required field related *

<label for="FirstName">First Name *:</label>
like image 144
Johannes Setiabudi Avatar answered Jan 04 '23 02:01

Johannes Setiabudi


Just write a regular <label> element in plain HTML:

<label>My Label:</label>

If you want to output the for="" attribute and accurately render the control's name then use this extension method:

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

namespace MvcLibrary.Extensions 
{ 
    public static class HtmlExtensions 
    { 
        public static MvcHtmlString FieldIdFor<TModel, TValue>(
            this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 
        { 
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 
            string inputFieldId = html.ViewContext.ViewData.
                                      TemplateInfo.GetFullHtmlFieldId(htmlFieldName); 
            return MvcHtmlString.Create(inputFieldId); 
        } 
    } 
}

Then you can use in your view like so:

<label for="<%= Html.FieldIdFor(m => m.EmailAddress) %>">E-mail address:</label> 
<%= Html.TextBoxFor(m => m.EmailAddress) %>

The other posts cover different approaches, they are all equally valid, which one you go for is matter of personal preference. I personally prefer writing the <label> as plain HTML as it gives designers more flexibility with changing markup, adding extra attributes such as CSS classes etc. Also I feel the label text is a view concern and shouldn't be decorated on the ViewModel class, but that's just my personal opinion/preference, I know some people here will disagree with me and that's fine :-)

like image 40
Sunday Ironfoot Avatar answered Jan 04 '23 01:01

Sunday Ironfoot