Rectangle 27 0

javascript angularjs newline filter with no other html?


<p style="white-space: pre;">{{ MyMultiLineText}}</p>

+1 WOW. This is an incredible solution that takes into account that we'd rather not rely on our own escaping abilities. We need to be able to display line breaks without compromising XSS protections.

+1, this is by far the simplest solution and seems to be suitable for many needs. Indeed, pre-line is probably better in general, since long rows will be wrapped (as they would with any <br> based solutions).

All you have to do is display the text within an element that has this CSS:

Maybe you can achieve this only with html, a <preformated text> way ? It will avoid from using filters or do any kind of processing.

This will parse and display \n as new lines. Works great for me.

pre-line, was a better option for me.

Note
Rectangle 27 0

javascript angularjs newline filter with no other html?


<span ng-bind-html-unsafe="dataFromModel | noHTML | newlines"></span>
App.filter('newlines', function () {
    return function(text) {
        return text.replace(/\n/g, '<br/>');
    }
})
.filter('noHTML', function () {
    return function(text) {
        return text
                .replace(/&/g, '&amp;')
                .replace(/>/g, '&gt;')
                .replace(/</g, '&lt;');
    }
});
text.replace(/(\\r)?\\n/g, '<br />')
text.replace(/\\n/g, '<br />')

@BarthZalewski - You only need `\` when compiling a regex from a string. When using a regex literal you don't have to escape slashes.

Instead of messing with new directives, I decided to just use 2 filters:

You can now skip the noHtml filter if you want and just add the newLines filter to ng-bind-html. ngSanitize will take care of the rest.

Note
Rectangle 27 0

javascript angularjs newline filter with no other html?


<p ng-repeat="line in (line.message | newlines)">{{line}}</p>
<span ng-repeat="line in (text | newlines) track by $index">
    <p> {{line}}</p>
    <br>
</span>
App.filter('newlines', function() {
  return function(text) {
    return text.split(/\n/g);
  };
});

A simpler way to do this is to make a filter that splits the text at each \n into a list, and then to use `ng-repeat.

Good answer, but better use track by in case of duplicate lines, which would raise an error: line in (text | newlines) track by $index.

and in the html:

Note
Rectangle 27 0

javascript angularjs newline filter with no other html?


<div no-html="data" post-filter="newlines"></div>
app.directive('noHtml', function($filter){
  return function(scope, element, attrs){
    var html = scope[attrs.noHtml];
    var text = angular.element("<div>").html(html).text();

    // post filter
    var filter = attrs.postFilter;
    var result = $filter(filter)(text);

    // apending html
    element.html(result);
  };
});

I'm not aware if Angular has a service to strip html, but it seems you need to remove html before passing your newlines custom filter. The way I would do it is through a custom no-html directive, which would be passed a scope property and the name of a filter to apply after removing the html

The following part is applying the newline filter, which is done using the $filter service.

The important bit is the text variable. Here I create an intermediate DOM element and append it the HTML using the html method and then retrieve only the text with the text method. Both methods are provided by Angular's lite version of jQuery.

Note