Question

In my ViewModel there is a property that needs a 2 line label but when I place a <br /> in the DisplayName attribute the HTML code is printed to the page instead of being interpreted as a line break. Is there a way to get a DisplayName to have a line break in it?

View:

    <tr>
        <td>
            @Html.LabelFor(m => m.GrossGallons)
        </td>
        <td>
        </td>
    </tr>

ViewModel:

    [DisplayName("Gross Gallons <br /> (Max: 6,000)")]
    public decimal GrossGallons { get; set; }

Output trying to get:

Gross Gallons
(Max: 6,000)
Was it helpful?

Solution

There is a simple way of doing this - use \n instead of <br />, and use CSS to make it work.

Model:

[DisplayName("Gross Gallons\n(Max: 6,000)")]
public decimal GrossGallons { get; set; }

CSS:

label { white-space: pre-wrap; }

I would recommend making the CSS selector as specific as possible, so as not to catch other labels (in case you're using labels by hand elsewhere, where your source code may contain whitespace). For example, in bootstrap I would've applied this to label.control-label.

You could also attach a more specific style to that label only, and style only that class.

@Html.LabelFor(m => m.GrossGallons, new { @class = "multiline-label" })

OTHER TIPS

I can think of a few options.

1) You could use @Html.Raw(). You can replace the string I have entered with a reference to a string.

@Html.Raw("Gross Gallons <br /> (Max: 6,000)");

1a) If you need to set it in the DisplayName attribute, then you might try using Html.Raw() but accessing the value through reflection. (Note: I haven't tried this, so don't know if it is possible)

2) You could use css styling to force the line to wrap where you want it to.

3) You could create a custom extension method or custom attribute to do this for you.

you can use @Html.Raw(), I think this is the most simple way.

It's not pretty, but you could use EditorTemplates and create a _layout.cshtml that all your Templates use. Then use this to pull/display the DisplayName:

<div class="form-group">
    <label for="@ViewData.ModelMetadata.PropertyName">
        @Html.Raw(ViewData.ModelMetadata.GetDisplayName())
    </label>
    @RenderBody()
    @Html.ValidationMessageFor(x => x)
</div>

The serious drawback to this is you would have to create EditorTemplates for each of your types like this sample string.cshtml template:

@model string
@{
    Layout = "_Layout.cshtml";
}
@Html.TextBoxFor(x => x, new { @class="form-control" })

A little off-topic but going this route allows me to encapsulate wrapping HTML around my form elements, so my forms in the views end up really simple like this:

<fieldset>
  @Html.EditorFor(x => x.Email)
  @Html.EditorFor(x => x.Address1)
  @Html.EditorFor(x => x.Address2)
  @Html.EditorFor(x => x.City)
</fieldset>

If use LabelFor(), another "possible" solution is to implement your own using the original source as a guide.

Replace

tag.SetInnerText(resolvedLabelText);

with

tag.InnerHtml = resolvedLabelText;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top