docs/content/tutorial/step_11.ngdoc
@ngdoc tutorial
@name 11 - Custom Filters
@step 11
@description
<ul doc-tutorial-nav="11"></ul>
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.
<div doc-tutorial-reset="11"></div>
## 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.
<br />
**`app/core/core.module.js`:**
```js
angular.module('core', []);
```
<br />
**`app/core/checkmark/checkmark.filter.js`:**
```js
angular.
module('core').
filter('checkmark', function() {
return function(input) {
return input ? '\u2713' : '\u2718';
};
});
```
<div class="alert alert-info">
As you may have noticed, we (unsurprisingly) gave our file a `.filter` suffix.
</div>
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.
<br />
**`app/app.module.js`:**
```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.
<br />
**`app/index.html`:**
```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:
<br />
**`app/phone-detail/phone-detail.template.html`:**
```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.
<br />
**`app/core/checkmark/checkmark.filter.spec.js`:**
```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 {@link angular.mock.inject angular.mock.inject()}.
<div class="alert alert-info">
When injecting a filter, we need to suffix the filter name with 'Filter'. For example, our
`checkmark` filter is injected as `checkmarkFilter`.
See the [Filters](guide/filter#using-filters-in-controllers-services-and-directives) section of
the Developer Guide for more info.
</div>
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
<div></div>
* Let's experiment with some of the {@link api/ng/filter 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`:
```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 {@link step_12 step 12}
to learn how we can use AngularJS to enhance the phone details page further.
<ul doc-tutorial-nav="11"></ul>