In this step you will learn how to create your own custom display filter.
- In the previous step, the details page displayed either "true" or "false" to indicate whether certain phone features were present or not. In this step, we are using a custom filter to convert those text strings into glyphs: ✓ for "true", and ✘ for "false".
Let's see what the filter code looks like.
Reset the workspace to step 11.
git checkout -f step-11
Refresh your browser or check out this step online: Step 11 Live Demo.
The most important changes are listed below. You can see the full diff on GitHub.
The checkmark
Filter
Since this filter is generic (i.e. it is not specific to any view or component), we are going to
register it in a core
module, which contains "application-wide" features.
app/core/core.module.js
:
angular.module('core', []);
app/core/checkmark/checkmark.filter.js
:
angular.
module('core').
filter('checkmark', function() {
return function(input) {
return input ? '\u2713' : '\u2718';
};
});
.filter
suffix.
The name of our filter is "checkmark". The input
evaluates to either true
or false
, and we
return one of the two unicode characters we have chosen to represent true (\u2713
-> ✓) and false
(\u2718
-> ✘).
Now that our filter is ready, we need to register the core
module as a dependency of our main
phonecatApp
module.
app/app.module.js
:
angular.module('phonecatApp', [
...
'core',
...
]);
Templates
Since we have created two new files (core.module.js, checkmark.filter.js), we need to include them in our layout template.
app/index.html
:
...
<script src="core/core.module.js"></script>
<script src="core/checkmark/checkmark.filter.js"></script>
...
The syntax for using filters in AngularJS templates is as follows:
{{expression | filter}}
Let's employ the filter in the phone details template:
app/phone-detail/phone-detail.template.html
:
...
<dl>
<dt>Infrared</dt>
<dd>{{$ctrl.phone.connectivity.infrared | checkmark}}</dd>
<dt>GPS</dt>
<dd>{{$ctrl.phone.connectivity.gps | checkmark}}</dd>
</dl>
...
Testing
Filters, like any other code, should be tested. Luckily, these tests are very easy to write.
app/core/checkmark/checkmark.filter.spec.js
:
describe('checkmark', function() {
beforeEach(module('core'));
it('should convert boolean values to unicode checkmark or cross',
inject(function(checkmarkFilter) {
expect(checkmarkFilter(true)).toBe('\u2713');
expect(checkmarkFilter(false)).toBe('\u2718');
})
);
});
The call to beforeEach(module('core'))
loads the core
module (which contains the checkmark
filter) into the injector, before every test.
Note that we call the helper function inject(function(checkmarkFilter) {...})
, to get access to
the filter that we want to test. See also angular.mock.inject().
checkmark
filter is injected as checkmarkFilter
.
See the Filters section of
the Developer Guide for more info.
You should now see the following output in the Karma tab:
Chrome 49.0: Executed 4 of 4 SUCCESS (0.091 secs / 0.075 secs)
Experiments
Let's experiment with some of the built-in AngularJS filters. Add the following bindings to
index.html
:{{'lower cap string' | uppercase}}
{{{foo: 'bar', baz: 42} | json}}
{{1459461289000 | date}}
{{1459461289000 | date:'MM/dd/yyyy @ h:mma'}}
We can also create a model with an input element, and combine it with a filtered binding. Add the following to
index.html
:<input ng-model="userInput" /> Uppercased: {{userInput | uppercase}}
Summary
Now that we have learned how to write and test a custom filter, let's go to step 12 to learn how we can use AngularJS to enhance the phone details page further.