92

After reading AngularJS tutorial step-9 I have created my own AngularJS filter, which should convert boolean data into html.

Here is my filter code:

angular.module('phonecatFilters', []).filter('iconify', function () { // My custom filter
    return function (input) {
        return input ? '<i class="icon-ok"></i>' : '<i class="icon-remove"></i>';
    }
});

Here is my HTML code:

<dt>Infrared</dt>
  <dd>{{phone.connectivity.infrared | iconify }}"></dd>

The problem is that borwser displays returned value literally as:

<i class="icon-ok"></i>

not as icons (or rendered html) that should appear.

Here is JSFiddle example

I think that some sanitisation occurs during this process.

Is it possible to turn this sanitization off for this specific filter?

Also I know how to display icons by not returning HTML output from filter but rather just 'ok' or 'remove' text which I can then substitute to:

<i class="icon-{{phone.connectivity.infrared | iconify}}"><i>

but this is not what I want.

3 Answers 3

113

You should use the ng-bind-html directive (require to import the sanitize module and js file): https://docs.angularjs.org/api/ng/directive/ngBindHtml

<span ng-bind-html='phone.connectivity.infrared | iconify'></span>

You also need to import the CSS (Bootstrap I guess) to be able to see the icon when it works.

I have provided a working example.

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

7 Comments

Well it's the only way I know to output raw html with angularJS and this binding is only allowed on attributes so you don't have much choice, you can write you own directive that accept comments or elements bindings, take the source code of bind-html for a starting point: github.com/angular/angular.js/blob/master/src/ngSanitize/…
A directive maybe the nicest solution here <check-icon ng:model='phone.connectivity.infrared'></check-icon> but it's not really shorter than your solution ;)
One thing to note is that you need to include the angular-sanitize.js file for this to work. If you want to do the same without including this extra library, you can use the ng-bind-html-unsafe directive.
angular 2.x drops ng-html-bind-unsafe and requires the html contents to be explicit marked as 'safe' - see: docs.angularjs.org/api/ng.$sce#Example
There should be a default filter html_safe: {{myContent | myFilter | html_safe}}
|
17

Unless I am reading it wrong, you are approaching in the wrong way.

I think ng-class is the directive you need for this job and is safer than rendering to class attribute.

In your case just add object string with the id strings as the class and the value as the evaluated expression.

<i ng-class="{
'icon-ok':!phone.connectivity.infrared,
'icon-remove':phone.connectivity.infrared
}"></i>'

On a side note, you should only use directives (built-in and custom) to manipulate html/dom and if you needed a more complex html render you should look at directive instead.

1 Comment

Good solution. Or done a bit simpler: <i ng-class="phone.connectivity.infrared ? 'icon-ok' : 'icon-remove'"></i>
12

Try this filter

filter('trust', ['$sce',function($sce) {
  return function(value, type) {
    return $sce.trustAs(type || 'html', value);
  }
}]);

requires angular-sanitize

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

Gist Link

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.