Improve this Doc

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.

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

As you may have noticed, we (unsurprisingly) gave our file a `.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().

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 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.