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
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);
//
}
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!');
});
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/
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
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>