AngularJS filter with trustAsHtml - angularjs

I'm trying to make a custom filter that replaces new lines with <br/>, like this:
angular.module('appFilters', []).filter('break_lines', ['$sce', function($sce) {
return function(input) {
return $sce.trustAsHtml(input.replace(/\n/g, "<br />"));
};
}]);
And use it in a template like this:
<div class="home-tag">{{locales.home_tagline | break_lines}}</div>
The problem is that the resulting text is html escaped.

Try
<div class="home-tag" ng-bind-html="(locales.home_tagline | break_lines)"></div>
Hope it helps

Related

AngularJS - Use function as filter inside controller

If I have a filter defined
app.filter('filterName', function() {
return function(var) {
// Some filter stuff
}
}
I can invoke it on controller doing $filter('filterName')($scope.someObj);.
But, here is my question, if I have a function that use as a filter
$scope.myFilterFunction = function() {
return true;
}
In my HTML
<p ng-repeat="item in items | filter:myFilterFunction">{{item}}</p>
How can I use this function filter in the controller (I have tested with $filter but throws an error).
Thanks in advance.
If you already implement the custom filter filterName, why not use it?
Try
<p ng-repeat="item in items | filterName">{{item}}</p>
Updated
You just missing the parentheses.
<p ng-repeat="item in items | filter:myFilterFunction()">{{item}}</p>
Inject $filter in the controller and use it with your filter name.
controller.$inject = ['$filter'];
function controller($filter){
// code here
$filter('filterName')(arg1,arg2);
//
}

AngularJS using a custom filter in the html tag of a custom directive?

I have a directive with a template that looks like:
<span> {{foo.bar}} {{foo.car}} {{foo.dar}}</span>
which is called in multiple locations. The way it is called is:
<foo-dir foo="fooData"></foo-dir>
Is there any way to apply a custom filter in the html directive tag and not in the directive itself?
I'm hoping something exists such as:
ng-innertext-filter="filterName:params"
but it may be wishful thinking.
If that is not possible, is there a way to use the filter in the directive controller without having to apply it everywhere the directive is used?
Thanks.
Edit: filter code:
import angular from 'angular';
function someFilter() {
return (input, filterParam) => {
if (input && filterParam && input.length)
if(filterParam)
return input.filterLogic();
return input;
}
}
The filter works fine when in a templated string {{somedata | someFilter}}. But I am looking for a way to apply the filter to the directive tag itself.
To do exactly what you want:
use the filter on the resulting string from a directive in the html tag
you need to create a template string and recompile your DOM.
This is a quite advanced use of AngularJS. I hope you enjoy it :-)
var app = angular.module("app", []);
app.controller('ctrl', function ($scope) {
$scope.foo = {
bar: "1",
car: "2",
dar: "3"
};
});
app.directive('foodir', function ($compile) {
return {
restrict: 'E',
scope: {
foo: '=', // Bind the variable to the directive's scope
filter: '#' // Just get the string for compilation
},
link: function ($scope, $element, $attrs) {
// This is the string on which you may want to apply a filter
var string_template = '" bar:" + foo.bar + " car:" + foo.car + " dar:" + foo.dar';
// Full string to compile without filter
var html = '<span>{{' + string_template + '}}</span>';
if ($scope.filter !== undefined)
// Full string to compile with filter (optional)
html = '<span>{{' + string_template + ' | '+$scope.filter+'}}</span>';
console.log(html);
var e = $compile(html)($scope); // Convert your string to a DOM element
$element.replaceWith(e); // Make it the content of the directive
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="app" ng-controller="ctrl">
<foodir foo="foo"></foodir>
<hr/>
<foodir foo="foo" filter="uppercase"></foodir>
<hr/>
<foodir foo="foo" filter="limitTo:10"></foodir>
</body>
Now, if you just want to apply a filter to some parts of your template (and not the full string), you can avoid the string_template and use basic interpolation like this:
var html = '<span> {{foo.bar}} {{foo.car}} {{foo.dar |' + $scope.filter + '}}</span>'
I'm not sure what the first part of your question means. If you're wanting to apply this filter to the compiled result of a directive, I'm not sure you can. I can help with using a filter in a controller, though.
If you define a custom AngularJS filter like so:
app.filter('makeItPretty', function() {
return function(value) {
return value.toUpperCase();
};
});
Then you can access your filter from within a controller by injecting the built-in $filter service:
app.controller('MyController', function($filter) {
var makeItPretty = $filter('makeItPretty');
var myPrettyText = makeItPretty('tHiS iS UgLy!');
});

Replace {{test}} with DOM "<div>example</div>"?

Is there any way to replace a controller's $scope.test with actual HTML? I know that you can set $scope.test to numbers, letters, etc, but how would you inject a template into the binding?
Are you talking about having $scope.test = '{{test}}' and then getting that to parse further, or are you talking about something like $scope.test = '<div>example</div>'.
If it's the later, just do what I did and set it to a string that includes the HTML. If $scope.test is coming from somewhere (like a form input) and you can't just set the variable directly, you could also create a custom filter and do something like {{test|wrapInDiv}}.
Here is an example filter:
angular.module('myapp', [])
.filter('wrapInDiv', function() {
return function (input) {
return '<div>' + input + '</div>';
};
});
As ebinmanuval mentioned, you can also use ng-bind-html which outputs the HTML as a child of the element you put the ng-bind-html on.
<p ng-bind-html="test"></div>
Where test is the $scope.test variable.
use ng-bin-html with custom trust filter to bind html to dom
<span ng-bind-html="test |trust"></span>
.filter('trust', [
'$sce',
function($sce) {
return function(value, type) {
return $sce.trustAsHtml(value);
}
}
]);
checkout https://jsfiddle.net/ebinmanuval/0tLso4vg/

Angular filter to replace single quotes

I have the following filter that seems like it should be working in my view. When added to the directive no data is returned, just as if the data contained a single quote as in "it's".
angular.module('hcApp')
.filter('replace', function(){
return function(text) {
return text.replace(/'/g, '"');
};
});
I'm trying to escape single quotes from my JSON data, which is coming through a CMS. Could it possibly be a conflict with the filters and directive already in place?
<div ng-bind-html="'{{over.contents}}' | to_trusted | replace "></div>
angular.module('hcApp')
.filter('to_trusted', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
You don't need to interpolate the value ('{{over.contents}}'). And you want to_trusted to be the last filter because it wraps the string to tell Angular it's trusted. Try this...
<div ng-bind-html="over.contents | replace | to_trusted "></div>
Also, " is a double quote. For a single quote, use '.
Fiddle

How to output HTML in angularjs with just using filter

I'm able to unescape the string that has some markup in it using ngSanitize and in HTML I use
<span ng-bind-html="myHTML"></span>
I've created a filter
.filter('safe', function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
})
I wonder if I can do something like this instead?
<span>{{ myHTML | safe }}</span>
Right now it does not really work and I'm trying to see what I'm missing.
You can make your own filter for that:
var app = angular.module('yourModuleName');
app.filter('safe', function($sce) {
return function(htmlString) {
return $sce.trustAsHtml(htmlString);
}
};
Your markup would be something like:
<span ng-bind-html="myHTML | safe"></span>

Resources