-1

I laying out a styleguide with code examples within an AngularJS app.

In the past, I've used <pre>. This no longer seems to work. I've tried it in codepen, and it still parses the HTML.

I do not want this.

<h1>I DO want this.</h1>

I'm guessing there's a filter to encode or decode the HTML, but I don't know which way I need to go. My intuition tells me I need to encode. However, everytime I try to google search a solution I get the opposite answers of what I want.

So for anyone who's better at googling than I am or know how to do this, please help.

Edit To appease the would be SO demigods, where's the code I ended up with...

This is how I started:

<xmp><button>Some example Button</button></xmp>

<xmp> is deprecated, and has line break/whitespace issues. Couldn't use it.

Next one...

<pre><button>Some example Button</button></pre>

This sucked too, because it still parses the child nodes, meaning would get a button instead of a string.

What I ended up with:

// Template

    <div class="sgForms__ex">
        <div ng-bind-html="sgTrustHtml(buttons)"></div>
    </div>
    <div class="sgForms__code">
        <div ng-bind="buttons"></div>
    </div>

// Controller

angular.module('StyleGuide')
  .controller('StyleGuideFormsController', ['$scope', '$sce', 'ListHelper',
  function ($scope, $sce, listHelper) {

    $scope.sgTrustHtml = function (i) {
        return $sce.trustAsHtml(i);
    };

    $scope.buttons = '<button type="button" class="btn btn-primary">Call to Action</button>' +
        '<button type="button" class="btn btn-default">Secondary CTA</button>'+
        '<button type="button" class="btn btn-default">Inactive</button>';


}]);

I'm still running into an issue with line breaks. Note sure how I'm going to work around that.

11
  • did you tried ng-bind-html directive? Commented Feb 12, 2016 at 19:21
  • @PankajParkar so store the HTML to a $scope and then pop it in? stackoverflow.com/a/14514299/1202630 Commented Feb 12, 2016 at 19:28
  • You have to show your code, where's there a scope value being set? Text is typically HTML-escaped by default, so it's hard to tell what you're doing. Commented Feb 12, 2016 at 19:46
  • <pre> never behaved the way you describe. <xmp> does. Commented Feb 12, 2016 at 19:50
  • @DanielBeck <xmp> is deprecated. There's also line breaking and whitespace issues. with it. Commented Feb 12, 2016 at 19:53

2 Answers 2

2

The only problem with the code you've shown is that you are using buttons but the scope only has examples. The following snippet shows the HTML parsed, and unparsed.

To display newlines where you are displaying the code, just wrap it with a pre (or use CSS white-space: pre)

var myApp = angular.module('myApp', [])
  .directive('myDirective', ['$sce',function($sce) {}])
  .controller('StyleGuideFormsController', ['$scope', '$sce',
    function($scope, $sce) {
      $scope.sgTrustHtml = function(htmlString) {
        return $sce.trustAsHtml(htmlString);
      };

      $scope.examples = '<button type="button" class="btn btn-primary">Call to Action</button>\n' +
        '<button type="button" class="btn btn-default">Secondary CTA</button>\n' +
        '<button type="button" class="btn btn-default">Inactive</button>';
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">

  <div ng-controller="StyleGuideFormsController">
    <pre><div ng-bind="examples"></div><pre>
    <div ng-bind-html="sgTrustHtml(examples)"></div>
  </div>

</div>

Sign up to request clarification or add additional context in comments.

3 Comments

@DanielBeck Fixed it
the examples bit was a typo from carrying over to the answer. In my code, using ng-bind works, but I don't know how to persist lines breaks.
@Plummer The focus of your question was displaying the code instead of interpreting the code. If you put a pre around the HTML that displays your code, then newlines will be treated as new lines instead of collapsed into whitespace like HTML usually does.
-1

You can use a function strip_tags to clean up your code.

angular.module('filters', []).factory('truncate', function () {
    return function strip_tags(input, allowed) {
      allowed = (((allowed || '') + '')
        .toLowerCase()
        .match(/<[a-z][a-z0-9]*>/g) || [])
        .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
      return input.replace(commentsAndPhpTags, '')
        .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
        });
    }
});

Controller:

angular.module('myApp', ['filters'])
.controller('IndexController', ['$scope', 'truncate', function($scope, truncate){

  $('#myDivPre').replaceWith((truncate($('#myDiv'), '<a><br>')));

}]);

HTML:

<div id="myDivPre"></div>

4 Comments

Isn't this the opposite of what the OP wants, they don't want to strip, they want to maintain the tags.
@JuanMendes: And I love the downvotes fairies paying me a visit because they don't understand the question.
@Plummer One of the downvotes was mine (for the question, not this answer since Jean just misunderstood the question), I kind of understood it. However, in my book, a question without code is always worth a downvote, you did not explain well what you are currently doing.
@JuanMendes my bad, dude. I was using <pre> which doesn't work. The example I gave are essentially what SO does already, which is what I posted. If you inspect SO, they use <pre>, but I'm sure they have some JS driving it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.