views:

49

answers:

5

hi!

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

+1  A: 

You can create a String.ascx in DisplayTemplates folder and provide your own implementation. Refer to the Overriding Templates section of the following article.

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

Amitabh
A: 

I think the best approach would be writing your own helper method that renders what you like. You can overload the existing method or simply create a new method.

Matteo Mosca
A: 

You could do this using MVC 2 (if possible) if you pass a custom ViewModel to the view.

using System.ComponentModel;

 public class PersonViewModel
    {
        public PersonViewModel(string name)
        {
            this.Name = name;
        }

        [DisplayName(".Display Anything You Like Here.")]
        public string Name { get; set; }
Kohan
+1  A: 

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 :-)

Sunday Ironfoot
+1  A: 

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>
Johannes Setiabudi
i like this one. I think it will be the way i will do it.. by overriding or create a new one that i will what i want.
Alexandre Jobin