AngularJS lets us format data or manipulate array collections through filters. In this example we’ll take a look at the formatting filters.
To specify a filter in the HTML template, we can use the common data biding notation {{expression}} and add a pipe (|) after the expression to format its result, so we’ll have something like this {{expression | filter}}. If the filter accepts some parameters, we can specify them in sequence with the colon (:) character {{expression | filter:param1:param2}}.
Angular exposes a simple API for creating a filter. Just as you would declare a controller with app.controller(‘myCtrl’, function(){});, you can create a new filter by appending .filter(‘filterName’, function(){}) to your Angular app.
Formatting Credit card and Telephone Number
Requirement – To filter currency to format 10 digits to (555) 555-5255 and also have a credit card field that is mapped to AngularJS, like:
<input type=”text” ng-model=”customer.creditCardNumber”>
which usually returns the whole number (4111111111111111). But to format credit card data to mask it with xxx the first 12 digits and only show the last 4.
Solution – We make use of a custom filter as
angular.module(‘ng’).filter(‘tel’, function () {
return function (tel) {
if (!tel) { return ”; }
var value = tel.toString().trim().replace(/^\+/, ”);
if (value.match(/[^0-9]/)) {
return tel;
}
var country, city, number;
switch (value.length) {
case 10: // +1PPP####### -> C (PPP) ###-####
country = 1;
city = value.slice(0, 3);
number = value.slice(3);
break;
case 11: // +CPPP####### -> CCC (PP) ###-####
country = value[0];
city = value.slice(1, 4);
number = value.slice(4);
break;
case 12: // +CCCPP####### -> CCC (PP) ###-####
country = value.slice(0, 3);
city = value.slice(3, 5);
number = value.slice(5);
break;
default:
return tel;
}
if (country == 1) {
country = “”;
}
number = number.slice(0, 3) + ‘-‘ + number.slice(3);
return (country + ” (” + city + “) ” + number).trim();
};
});
Then use this filter in template
{{ phoneNumber | tel }}
<span ng-bind=”phoneNumber | tel”></span>
Preserve HTML
By default, AngularJS will turn your HTML into normal text, in other words: make it safe so that by default people can’t insert any unwanted HTML into your page.
For this example, let’s assume you have some data that needs to be displayed on the page and that you have made an AngularJS App for it. I called mine commentApp with some spoofed (fake) data that I just hardcoded.
We’ll assume that you have replaced line breaks (if necessary) with a <br />
var commentApp = angular.module(‘commentApp’, []);
commentApp.controller(‘CommentCtrl’, function ($scope) {
$scope.comments = [
{
‘name’ : ‘Some Guy’,
‘text’ : ‘This is cool.’
},
{
‘name’ : ‘John Doe’,
‘text’: ‘Hi, I am John Doe. This is a single-line comment to be displayed with AngularJS’
},
{
‘name’ : ‘Jane Doe’,
‘text’ : ‘Jane doe is the female version of “John Doe”.<br />This is a new line to be displayed with AngularJS’
}
];
});
You could then use the following HTML to output the data:
<section id=”comments” ng-app=”commentApp” ng-controller=”CommentCtrl”>
<ul id=”comment-list”>
<li ng-repeat=”comment in comments”>
<a href=”#” class=”profile-link”>
{{comment.name}}
</a>
<p>
{{comment.text}}
</p>
</li>
</ul>
</section>
The problem now is, that instead of a new line, the text “<br />” will be part of the comment text.
You now have to use $sce to run your output through a filter, which you can specify to allow the HTML.
We can implement this using $sce.trustAsHtml() by adding a filter to our code (outside of the controller). This custom filter will make sure that our HTML doesn’t get filtered out by AngularJS 1.2/AngularJS 1.3 or later
We will name this filter “unsafe”. It gets passed a value, which we will return as trusted HTML output.
commentApp.filter(‘unsafe’, function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
});
Now, modify your HTML code from this:
<p>
{{comment.text}}
</p>
And change it to this:
<p ng-bind-html=”comment.text | unsafe”></p>
This will run your comment.text through the “unsafe” filter we just created, and once again, your output will have the HTML parsed properly.