Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular displaying multiple lined strings on one line

I am trying to get a string to be displayed on a webpage through Angularjs which may have multiple lines. Here is what I have got:

<textarea ng-model="StringValue"></textarea>
{{StringValue}}

When you type into the textarea:

"This is

a string"

you get:

"This is a string"

How do you get it so the text is displayed the same way it is typed?

like image 749
Luke Drew Avatar asked Aug 29 '13 14:08

Luke Drew


3 Answers

Be careful with ng-bind-html - very easy to get XSS-injection.

If you want to show your newlines only, without XSS in your pages
you can use simple css-rule: white-space: pre:

<span style="white-space: pre">{{multilinetext}}</span>

Sure, you can make css-class for this:

<style>.pre {white-space: pre}</style>
<span class="pre">{{multilinetext}}</span>

Also, this method makes all whitespaces visible: leading spaces, multiple spaces tabs and so other.

like image 155
vp_arth Avatar answered Nov 11 '22 02:11

vp_arth


This is an issue with HTML. Not Angular. Angular is writing out exactly what you told it to.

In HTML, outside of a <pre> tag, endless whitespace (returns, tabs, spaces, etc) are all treated as one white space. This is why you need things like <br/> and &nbsp; if you're not using a <pre> tag block.

So try this in HTML just so you get an understanding of what's happening:

<h3>Plain DIV</h3>
<div>
Some
   text
      here
</div>

<h3>Now with non-breaking spaces and line breaks</h3>
<div>
Some<br/>
&nbsp;&nbsp;&nbsp;text<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;here<br/>
</div>

<h3>Now with a PRE tag</h3>
<pre>
Some
   text
      here
</pre>

Here's a Fiddle demonstrating the above.

You're going to need to style the PRE tag with some custom class to make it look like the other text on your page, though, because most default styles for <pre> are going to use mono-spaced (fixed-width) fonts like Courier or Consolas.

It's either that or you're going to have to write a filter in angular that processes spaces, tabs and line breaks into the proper markup. ... which will be a pain to maintain.

EDIT: with the understanding above, an Angular solution (if you don't just use PRE)

So the best solution, IMO, if you don't want to use the <pre> tag would be to create a filter that will scrub the text for you and farmat it with line breaks and non-breaking spaces.

Something like this

app.filter('formatText', function (){
  return function(input) {
    if(!input) return input;
    var output = input
      //replace possible line breaks.
      .replace(/(\r\n|\r|\n)/g, '<br/>')
      //replace tabs
      .replace(/\t/g, '&nbsp;&nbsp;&nbsp;')
      //replace spaces.
      .replace(/ /g, '&nbsp;');

      return output;
  };
});

Then to use it you'd do something like this:

<span ng-bind-html="foo | formatText"></span>

Important to note:

  1. You'll need to include the angular-sanitize.js file in your script references.
  2. You'll need to require 'ngSanitize' in your module declaration:
var app = angular.module('myApp', ['ngSanitize']);

.. this is so you can use the ng-bind-html or ng-bind-html-unsafe directives.

Here is a plunk that demonstrates the usage.

like image 12
Ben Lesh Avatar answered Nov 11 '22 02:11

Ben Lesh


As other answer mentioned, you can use a filter to achieve it.

Let me implement it for you:

<textarea ng-model="StringValue"></textarea>
<div ng-bind-html-unsafe="StringValue | breakFilter"></div>

angular.module('myApp', []).filter('breakFilter', function () {
    return function (text) {
        if (text !== undefined) return text.replace(/\n/g, '<br />');
    };
});
like image 7
zs2020 Avatar answered Nov 11 '22 01:11

zs2020