Helper for LabelFor that wraps an HTML tag
I have several objects with long names and I would like them to abbreviate them in labels using an HTML tag abbr
. I am using DataAnnotations to provide a DisplayName value for a property in a view model (or entity class).
I did it manually:
<label class="myClass"><abbr title="@Html.DisplayFor(m => m.Ssn)">SSN</abbr> @Html.EditorFor(m => m.Ssn)</label>
but it becomes a pain. I would like to create a helper with the following syntax.
@Html.AbbrLabelFor(m => m.Ssn, "SSN")
and outputs:
<label for="Ssn"><abbr title="Social Security Number">SSN</abbr></label>
where Social Security Number is the DisplayName value and the second argument in the helper tag is the abbreviated text. So just adding a second argument to the mix.
The examples I've seen tend to discourage HtmlAttributes and the like, and I would like to keep this functionality as in:
@Html.AbbrLabelFor(m => m.Ssn, "SSN", new { @class="myClass" })
How do I extend an existing fully functional LabelFor to implement this, DfnLabel, etc.?
Your assistant should look like
public static MvcHtmlString AbbrLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string abbreviation, object htmlAttributes)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string name = ExpressionHelper.GetExpressionText(expression)
TagBuilder abbr = new TagBuilder("abbr");
abbr.MergeAttribute("title", metaData.GetDisplayName());
abbr.InnerHtml = abbreviation;
TagBuilder label = new TagBuilder("label");
label.MergeAttribute("for", name);
label.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
label.InnerHtml = abbr.ToString();
return MvcHtmlString.Create(label.ToString());
}
Edit (with overloads)
public static MvcHtmlString AbbrLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string abbreviation)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string name = ExpressionHelper.GetExpressionText(expression);
return AbbrLabelHelper(helper, metaData, name, abbreviation, null);
}
public static MvcHtmlString AbbrLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string abbreviation, object htmlAttributes)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string name = ExpressionHelper.GetExpressionText(expression);
return AbbrLabelHelper(helper, metaData, name, abbreviation, htmlAttributes);
}
private static MvcHtmlString AbbrLabelHelper(HtmlHelper helper, ModelMetadata metaData, string name, string abbreviation, object htmlAttributes)
{
TagBuilder abbr = new TagBuilder("abbr");
abbr.MergeAttribute("title", metaData.GetDisplayName());
abbr.InnerHtml = abbreviation;
TagBuilder label = new TagBuilder("label");
label.MergeAttribute("for", name);
label.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
label.InnerHtml = abbr.ToString();
return MvcHtmlString.Create(label.ToString());
}
source to share