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
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
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
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.
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; }
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 :-)
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>