51

I am sure this has been asked before but I cannot find the answer.

I have an AngularJS script that is pulling from a DB and then rendering to content. Everything is working correctly except a couple of places that I am trying to concatenate some words with new lines between them.

 **in the script.js**
groupedList[aIndex].CATEGORY = existingCategory+'\n'+thisCategory;
groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;

If I use the first line of the above code I don't see anything but there is not a new line in the redered html. If I use the second line the <br> get rendered as text and the output looks like this:

Instinct<br>Media

instead of

Instinct
Media

I can post the full script if that would be helpful but I am guessing there is something simple that I am just not seeing.

UPDATE Here is the full js

function qCtrl($scope, $filter, $http, $timeout){

    $scope.getCategories = function(){$http.post('quote.cfc?method=getCategories').success(function(data) { $scope.categories = data; });   }
    $scope.getClassifications = function(){$http.post('quote.cfc?method=getClassifications').success(function(data) {   $scope.classifications = data;  }); }
    $scope.getIndustries = function(){$http.post('quote.cfc?method=getIndustries').success(function(data) { $scope.industries = data;   }); }
    $scope.getKeywords = function(){$http.post('quote.cfc?method=getKeywords').success(function(data) { $scope.keywords = data; }); }
    $scope.getSources = function(){$http.post('quote.cfc?method=getSources').success(function(data) {   $scope.sources = data;  }); }

    $scope.getAllQuotes = function(){$http.post('quote.cfc?method=getAllQuotesJoined').success(function(data) { $scope.allQuotes = data;    }); }

    $scope.initScopes = function (){
        $scope.getCategories();
        $scope.getClassifications();
        $scope.getIndustries();
        $scope.getKeywords();
        $scope.getSources();
        $scope.getAllQuotes();
    }   
    $scope.initScopes();

    // SEARCH QUOTES
    $scope.filteredQuotes = $scope.allQuotes;
    $scope.search = {searchField:''};

    $scope.searchQuote = function(){
        var filter = $filter('filter');
        var searchCrit = $scope.search;
        var newlist = $scope.allQuotes;
        var groupedList = [];
        var idList = [];
        newlist = filter(newlist,{TESTQUOTE:searchCrit.searchField});
        for(i=0;i<10;i++){
            aIndex = idList.contains(newlist[i].TESTIMONIALID);
            if(aIndex >= 0){
                thisKeyword = newlist[i].KEYWORD;
                thisClassification = newlist[i].CLASSIFICATION;
                thisCategory = newlist[i].CATEGORY;
                existingKeyword = groupedList[aIndex].KEYWORD;
                existingClassification = groupedList[aIndex].CLASSIFICATION;
                existingCategory = groupedList[aIndex].CATEGORY;
                if(thisKeyword != '' && existingKeyword.indexOf(thisKeyword) == -1){
                    groupedList[aIndex].KEYWORD = existingKeyword+' - '+thisKeyword;
                } 
                if(thisClassification != '' && existingClassification.indexOf(thisClassification) == -1){
                    groupedList[aIndex].CLASSIFICATION = existingClassification+' \n '+thisClassification;
                } 
                if(thisCategory != '' && existingCategory.indexOf(thisCategory) == -1){
                    groupedList[aIndex].CATEGORY = existingCategory+'<br>'+thisCategory;
                }               
            } else {
                idList.push(newlist[i].TESTIMONIALID);
                groupedList.push(newlist[i]);
            }
        }
        $scope.filteredQuotes = groupedList;
      }
}
Array.prototype.contains = function ( needle ) {
   for (j in this) {
       if (this[j] == needle) return j;
   }
   return -1;
}

Here is the HTML

<div ng-repeat="q in filteredQuotes" class="well clearfix">
                        <h3>{{q.TITLE}}</h3>
                        <div class="row-fluid" style="margin-bottom:5px;">
                            <div class="span3 well-small whBG"><h4>Classification</h4>{{q.CLASSIFICATION}}</div>
                            <div class="span3 well-small whBG pipeHolder"><h4>Categories</h4>{{q.CATEGORY}}</div>
                            <div class="span3 well-small whBG"><h4>Key Words</h4>{{q.KEYWORD}}</div>
                            <div class="span3 well-small whBG"><h4>Additional</h4>Industry = {{q.INDUSTRY}}<br>Source = {{q.SOURCE}}</div>
                        </div>
                        <div class="well whBG">{{q.TESTQUOTE}}</div>
                        <div class="tiny">
                            Source comment : {{q.SOURCECOMMENT}}<br>
                            Additional Comment : {{q.COMMENT}}
                        </div>
                    </div>
                </div>
Lance
  • 3,193
  • 2
  • 32
  • 49

6 Answers6

58

You can use \n to concatenate words and then apply this style to container div.

style="white-space: pre;"

More info can be found at https://developer.mozilla.org/en-US/docs/Web/CSS/white-space

<p style="white-space: pre;">
    This is normal text.
</p>
<p style="white-space: pre;">
    This 
  text 
  contains 
  new lines.
</p>
vinesh
  • 4,745
  • 6
  • 41
  • 45
  • It is not immediately obvious that, besides `\n`, CSS is also needed to enforce the newlines. Nice one. – dmvianna Sep 23 '15 at 00:57
  • thank you! angularjs modaltemplate ui-bootstrap text message – bbh Jul 23 '17 at 15:18
  • 3
    This is good. I use `white-space: pre-wrap;` for wrapping text – iMalek Oct 11 '17 at 13:57
  • 1
    This is the best and easiest answer. Too often {{messageText}} needs simple formatting and this by far is the easier method to do this. It allows you to customize these messages per message without having to worry about custom css formatting or html injection. – rolinger Oct 16 '19 at 20:29
  • simple and clean. working perfectly for me . Thanks!! – Sarjerao Ghadage Jun 08 '21 at 13:09
41

I could be wrong because I've never used Angular, but I believe you are probably using ng-bind, which will create just a TextNode.

You will want to use ng-bind-html instead.

http://docs.angularjs.org/api/ngSanitize.directive:ngBindHtml

Update: It looks like you'll need to use ng-bind-html-unsafe='q.category'

http://docs.angularjs.org/api/ng.directive:ngBindHtmlUnsafe

Here's a demo:

http://jsfiddle.net/VFVMv/

Shmiddty
  • 13,847
  • 1
  • 35
  • 52
25

You need to either use ng-bind-html-unsafe ... or you need to include the ngSanitize module and use ng-bind-html:

with ng-bind-html-unsafe

Use this if you trust the source of the HTML you're rendering it will render the raw output of whatever you put into it.

<div><h4>Categories</h4><span ng-bind-html-unsafe="q.CATEGORY"></span></div>

OR with ng-bind-html

Use this if you DON'T trust the source of the HTML (i.e. it's user input). It will sanitize the html to make sure it doesn't include things like script tags or other sources of potential security risks.

Make sure you include this:

<script src="http://code.angularjs.org/1.0.4/angular-sanitize.min.js"></script>

Then reference it in your application module:

var app = angular.module('myApp', ['ngSanitize']);

THEN use it:

<div><h4>Categories</h4><span ng-bind-html="q.CATEGORY"></span></div>
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • Thanks @blesh I marked Shimiddy as the answer since he's been helping me for the last hour but I will give you a vote up. Thanks again – Lance Feb 19 '13 at 19:09
  • No sweat. For a while there was a struggle on his answer, first where the wrong directive was being used, and then when it wasn't even being used properly... i.e. `ng-bind-html="{{blah}}"`. Looks like you worked it out as I was posting. – Ben Lesh Feb 19 '13 at 19:11
  • 4
    +1 I was hoping someone who actually knew Angular would show up. Haha. – Shmiddty Feb 19 '13 at 19:14
  • 1
    I was just watching. I learn more answering questions I *don't* know the complete answer to. I could tell you had most of the information you needed and that you would get there. It just appeared you had moved on so I added an answer. – Ben Lesh Feb 19 '13 at 19:24
3

Why so complicated?

I solved my problem this way simply:

  <pre>{{existingCategory+thisCategory}}</pre>

It will make <br /> automatically if the string contains '\n' that contain when I was saving data from textarea.

Dev
  • 1,592
  • 2
  • 22
  • 45
X-Coder
  • 2,632
  • 2
  • 19
  • 17
2

I've used like this

function chatSearchCtrl($scope, $http,$sce) {
 // some more my code

// take this 
data['message'] = $sce.trustAsHtml(data['message']);

$scope.searchresults = data;

and in html I did

<p class="clsPyType clsChatBoxPadding" ng-bind-html="searchresults.message"></p>

thats it I get my <br/> tag rendered

Ishak Ali
  • 340
  • 4
  • 10
0

You can also use:

String.fromCharCode(10);

with CSS

white-space: pre-line;

Here si working example: https://jsfiddle.net/Nxja/3xtcqdej/1/

Radim Šafrán
  • 463
  • 7
  • 16