Inserting line breaks in DisplayName attributes
Asked Answered
P

5

8

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)
Polysepalous answered 12/3, 2014 at 14:26 Comment(4)
Are you using @Html.EditorFor(...)?Sezen
Yes, I am using @Html.EditorFor() to display the input option.Polysepalous
possible duplicate of How to Insert Line Break using LabelFor in MVCPalmitin
@MatthewVerstraete - take a look at Darins answer here - #10478954. Basically, without resorting to hacks, you should make your own label creating Html helper so that you can render out the Html unencoded. I would simply use this everywhere in place of the standard Html.LabelFor so you don't have to track which labels have html and which ones don'tPalmitin
O
17

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" })
Omarr answered 12/3, 2014 at 19:27 Comment(0)
S
1

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.

Sporting answered 12/3, 2014 at 14:46 Comment(1)
1: That would defeat the purpose of using the @Html.LabelFor. 2: I really don't think using a CSS hack would be either efficient or proper to do. 3: I had thought about a custom extension but I was hoping there might be a simpler MVC solution.Polysepalous
C
0

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

Chloroprene answered 12/3, 2014 at 16:21 Comment(4)
That would defeat the purpose of using the @Html.LabelFor.Polysepalous
@Html.LabelFor is not @Html.Raw()Chloroprene
@Html.LabelFor is <label for=""></label>Chloroprene
I know the difference between the too HTML helpers. In my example I use the @Html.LabelFor() because I want the code to generate the <label /> tag. Moving to use the @Html.Raw defeats the entire reason of using @Html.LabelFor() in the first place. I am not even sure you could pass in the model and get the DisaplyName attribute to be parsed by the @Html.Raw helper.Polysepalous
S
0

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>
Sezen answered 12/3, 2014 at 17:6 Comment(5)
Why are you placing the label and validation message into the layout page instead of just right in the page where all the other form markup is at?Polysepalous
Because I only have to do it there once versus every time everywhere else. @Html.EditorFor() takes care of that for me.Sezen
Again, its not pretty. :-) I dont like the built in EditorFor templates so I usually end up writing my own for all the types anyway. Therefore its not a problem for me, however if you are fine with the built in, well then a lot of extra work....Sezen
But placing that in the layout template would screw up pages not displaying the form data or any form data that is using a model that does not have the DisplayPropery attribute, right?Polysepalous
Yes and No, if you use EditorFor it would drop in the Layout stuff. I only use EditorFor inside a standard form. GetDisplayName() returns PropertyName if the DisplayName attribute is not used.Sezen
S
0

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;
Sezen answered 12/3, 2014 at 19:20 Comment(1)
Not sure how this would work with EditorFor though.Sezen

© 2022 - 2024 — McMap. All rights reserved.