How to Create Custom Filter using AngularJS

What is Filter?

It is a process of extracting the actual input into a specific format. In other words it’s a process of forming a desire output. In AngularJS there are set of default filters which can be mostly used to format a expression or to change the display order if in case unordered list.

A Filter can be added to a expression using pipe (|) character and a filter.

Many of us might easily knew default filters provided in AngularJS. But a bit challenge is to create a custom filter in AngularJS. So here i’m going to give you explanation on creating various types of custom filters with example.

You can also view my post on use Filters in controller

  1. How to use Filter in controller with Example
  2. AngularJS – Multiple Filters in controller with Realtime Example

Filter #1: Filtering based on first character

Here we going create Filter for repeates. Filters are really handy for iterating over data and without much more work, we can do exactly that.

The syntax is quite similar as default one when filtering a repeat with custom filters, let’s take some example data:

app.controller('PersonCtrl', function () {
  this.friends = [{
    name: 'Andrew'        
  }, {
    name: 'Will'
  }, {
    name: 'Mark'
  }, {
    name: 'Alice'
  }, {
    name: 'Todd'
  }];
});

 

Let’s create a normal ng-repeat on it using unordered list:

<ul>
  <li ng-repeat="friend in person.friends">
    {{ friend }}
  </li>
</ul>

 

Add a filter called startsWithA (This name is user-defined one, it can be anything), where we only want to show names in the Array that beginning with A:

<ul>
  <li ng-repeat="friend in person.friends | startsWithA">
    {{ friend }}
  </li>
</ul>

So how do we create custom filter for this, or something similar?
Angular has a .filter() method for each Module, which means we can write our own custom filters. Let’s look at a stripped down filter.

The returned function gets invoked each time Angular calls the filter, which means two-way binding for our filters. The user makes a change, the filter runs again and updates as necessary. The name of our filter is how we can reference it inside Angular bindings.

Let’s create a new filter with the name startsWithA:

app.filter('startsWithA', function () {
  // function to invoke by Angular each time
  // Angular passes in the `items` which is our Array
  return function (items) {
    // Create a new Array
    var filtered = [];
    // loop through existing Array
    for (var i = 0; i < items.length; i++) {
      var item = items[i];
      // check if the individual Array element begins with `a` or not
      if (/a/i.test(item.name.substring(0, 1))) {
        // push it into the Array if it does!
        filtered.push(item);
      }
    }
    // boom, return the Array after iteration's complete
    return filtered;
  };
});

 

There are two different things happening here! First, the parameter items, which is our Array passed IN from the ng-repeat. The second thing is that we need to return a new Array.

So the output will be,


{"name":"Andrew"}
 
{"name":"Alice"}

Thats it !! We created our custom filter with repeats.

 

Filter #2: ng-repeat with Arguments

Pretty much the same as the above, but we can pass arguments into the functions from other Models. Let’s create an example that instead of “filtering by letter A”, we can let the user decide, so they can type their own example:

<input type="text" ng-model="letter">
<ul>
  <li ng-repeat="friend in person.friends | startsWithLetter:letter">
    {{ friend }}
  </li>
</ul>

Here I’m passing the filter the letter Model value from ng-model="letter". How does that wire up inside a custom filter?

app.filter('startsWithLetter', function () {
  return function (items, letter) {
    var filtered = [];
    var letterMatch = new RegExp(letter, 'i');
    for (var i = 0; i < items.length; i++) {
      var item = items[i];
      if (letterMatch.test(item.name.substring(0, 1))) {
        filtered.push(item);
      }
    }
    return filtered;
  };
});

The most important thing to remember here is how we’re passing in arguments! Notice letter now exists inside the return function (items, letter) {};? This corresponds directly to the :letter part. Which means we can pass in as many arguments as we need (for example):

<input type="text" ng-model="letter">
<ul>
  <li ng-repeat="friend in person.friends | startsWithLetter:letter:number:somethingElse:anotherThing">
    {{ friend }}
  </li>
</ul>

We’d then get something like this:

app.filter('startsWithLetter', function () {
  return function (items, letter, number, somethingElse, anotherThing) {
    // do a crazy loop
  };
});

and That’s it !!


 

 

One thought on “How to Create Custom Filter using AngularJS

Leave a Reply

Your email address will not be published.