unsafe_where_true
unsafe_where_true

Reputation: 6320

new lines, br in div plain text

OK this should be fairly simple...

Using angular. I output a text, which has been edited with a textarea:

{{model | newline2br}}

If I don't add the filter, all new lines are just ignored. So I did some googling, and wrote a filter, newline2br, which does just that - replacing new lines with <br />

But now the text is being displayed with literal <br />!

This is the output in the inspection window:

<div ng-show="showText" ng-mouseleave="showText = false" class="textwrapper ng-hide">asdjfhaslkjdfh aoiuyqoiweury iufyaoiusydf oiuaysdfiouy aiuysdfoiuy asdfo iuyasdf iouyasdfoiuy asdoifuy aoiusydf oiauysdfoiuays df oiauysdf iouaysdofiuy asioduyf aoiusydf oiauysdfo iuyasdoiufy aoisudyf oiuaysdifuy asdoiufysf<br />hello this is cool<br />I just found out that I can do shift-enter!<br />now I solved the problem with this... :))))</div>

Why is that? How do I write the filter correctly so that the div displays the new lines?

Upvotes: 1

Views: 1560

Answers (3)

tungd
tungd

Reputation: 14907

This is because AngularJS escape HTML tags in string (replace them with HTML entities) by default to save you from XSS and some other security problems as well. To display trusted content un-escaped you could use ngBindHTMLUnsafe (in older AngularJS version), or the the ngBindHTML ans SCE in 1.2 and newer. For example:

<div>{{sometext|newline2br}}</div>

Would be rewritten as (below 1.2):

<div ng-bind-html-unsafe="sometext|newline2br"></div>

With 1.2 and above:

<div ng-bind-html="sometext|newline2br|trusted"></div>

with the trusted filter:

app
  .filter('trusted', function($sce) {
    // You can use this one as `value|newline2br|trusted`, 
    // but I don't recommend it
    return function(input) {
      return $sce.trustAsHtml(input)
    }
  })

Or better with:

<div ng-bind-html="sometext|newline2br"></div>

and:

app
  .filter('newline2br', function($sce) {
    // This is my preferred way
    return function(input) {
      return $sce.trustAsHtml(input.replace(/\n/g, "<br>"))
    }
  })

Plunker: http://plnkr.co/LIxFVpi6ChtTLEni11qy

Upvotes: 4

C. S.
C. S.

Reputation: 823

you should probably have this as well, otherwise you will never see the text since it will never appear in the first place:

ng-init="showText=true"

The final thing you are looking for is, in addition to what tungd mentioned:

<div class="textwrapper" ng-bind-html-unsafe="model|newline2br" ng-init="showText=true" ng-show="showText" ng-mouseleave="showText = false">

Here is the fiddle to demonstrate.

Upvotes: 1

C. S.
C. S.

Reputation: 823

From my understanding, you are hiding the div, so the mouse can never go over it to show the div in the first place.

Upvotes: 0

Related Questions