When you're building web apps with AVR for .NET, it doesn't take very long to realize that HTML has a mind of its own. It's gonna do things its way, and it's usually up to you to trick it into doing things your way. Let's consider how HTML handles text with embedded carriage return/linefeeds (called 'newlines' for the rest of this article).

HTML ignores newlines by default in most HTML elements. One element that is an exception to this rule is the textarea element (the textarea element isn't available directly with ASP.NET controls, but it's what's rendered with ASP.NET when you set a TextBox control's TextMode property to multiline. The textarea element does honor newlines; when its contents are fetched (using the TextBox's Text property) it includes any newlines the user entered and renders the text correctly with them in place. If you're displaying text with newlines in it, and you want that text to be input capable, the textarea displays the text appropriately. However, you won't get the results you expect when you display text with newlines in it for output only.

Consider, for example, the fragment of an ASP.NET GridView shown below in Figure 1. This GridView has two modes, one for input/output and one for output only. This is the input/output mode (rendered as a textarea element). It shows that a user has entered a todo list with four items in it and each item is followed by a newline (there may or may not be a newline following the fourth item). When written to disk, the raw value does include the newline characters. When that value is read from disk later, it will contain these newline characters.

Although this article discusses the challenge of displaying text with newlines in a GridView control, the solution provided works with any HTML element.

Figure 1. A GridView with input-capable cells where the TodoList column is a textarea element.

Alas, when shown in read-only mode, it appears as though the newlines didn't persist, as shown below in Figure 2a.

Figure 2a. This output-only GridView ignores the newlines embedded in the ToDo List cell.

When you can use your browser's View->Source feature to take a look at the rendered HTML, you can see that although they aren't displayed correctly, the newlines are indeed in the cell's raw value--as shown below in Figure 2b.

Figure 2b. The newlines are there but the browser is ignoring them.

How do we get the newlines to render appropriately

I've been doing web development for at least 18 years and I'm embarrassed to tell you that I didn't know the simple trick that resolves this problem until about 60 days ago. I can't tell you how many times I've written code, either JavaScript on the client-side or AVR (and others) on the server-side to search and replace newline characters for the HTML tag so that the text would render appropriately. Those worries are behind us because CSS has your back!

Since at least 1997(!), CSS has included a property called white-space that when set to pre-wrap preserves all white space--including newlines. For many elements, this means that applying white-space to them is as simple as assigning a CSS rule that specifies white-space: pre-wrap to the element and boom, Bob's your uncle and the text displays appropriately.

To resolve the issue, you first need to create a CSS rule. Add the class CSS rule below to a CSS file that you're sure is included in the page with the issue (the safest place to add it is in a CSS file that is included with your master page). (The preceding dot (.) tells CSS this is a class selector.)

.show-white-space {
    white-space: pre-wrap;
}

In the absence of any CSS files to use (which is surely never the case!), you can add the necessary CSS class rule by embedding directly within the content page or master page's head tag like this :

<style>
    .show-white-space {
        white-space: pre-wrap;
    }
</style>

Next, go into the GridView's Fields property panel, navigate to the column not displaying newlines, and in its ItemStyle properties, add the CssClass name of show-white-space (note there is no leading dot provided here). Figure 3a below shows the added CSS class name.

Figure 3a. Adding the CSS class rule to the GridView column

With that CSS class rule added the text renders correctly in the GridView output column (as shown below in Figure 3b):

Figure 3b. With the CSS class rule applied, the GridView column now renders correctly.

You can see the white-space property in action with this CodePen.

CSS bonus round — another way to apply the CSS class rule

Here's an alternative way to apply the CSS property to a GridView column. The previous way shown works just fine and you probably won't have to do this, but for those of you looking to ramp your CSS knowledge a little, it's interesting to know about this way as well. If you do it this way, you won't need to add the CSS rule name to the column in the GridView.

First, at runtime, use your browser's View->Source feature to confirm the exact HTML DOM Id of your GridView. It will rarely be the Id you assigned to the GridView because of the way ASP.NET distorts client Ids at render time. (You can avoid that problem with the GridView's ClientId mode property, but that's another story!) In this case, the GridView with the runtime of Id of gridviewCust1 renders with a client Id of ctl00_content_gridviewCust1.

Using that Id, add a CSS Id rule as shown below in Figure 4. (The preceding hash (#) below tells CSS this is an Id selector.)

#ctl00_content_gridviewCust1 td:nth-child(2) { 
    white-space: pre-wrap; 
}

Figure 4. A CSS Id rule that applies the CSS white-space to the second column of the GridView's rendered HTML table.

This rule says, for the HTML element with an Id of #ctl00_content_gridviewCust1, apply the rules specified to second td tag. td elements the GridView's HTML table columns and they are one-based numbered. That is, if the column to which you need to apply the rule is the fourth column, you would have used:

#ctl00_content_gridviewCust1 td:nth-child(4) { 
    white-space: pre-wrap; 
}

This rule applies the white-space property to nth column of every row and, because of the way HTML elements inherit CSS properties from their parents, this rule applies the white-space property to anything within the td element.

To learn more about the topics covered in this article:



Please login or create an account to post comments.