Subscribe via RSS Feed

How To Use Filter In Angular.js

June 3, 2014 6 Comments

When we see an e-shopping or e-tutorial sites, we see a detailed search mechanism in the left in maximum scenario. Where we can put the exact credentials and get the product very fast and easy. So, what is it? It is a filter. A very unique and easy feature. Angular.js also supports this feature. Then, let us see  how to use filter in angular.js?
A filter formats the value of an expression for display to the user. They can be used in view templates, controllers or services and it is easy to define filter.The underlying API is the filterProvider.

Using filters in angular.js view templates:

Filters can be applied to expressions in view templates using the following syntax:

  {{ expression | filter }}

E.g. the markup {{ 12 | currency }} formats the number 12 as a currency using the currency filter. The resulting value is $12.00.
Filters can be applied to the result of another filter. This is called “chaining” and uses the following syntax:

  {{ expression | filter1 | filter2 | ... }}

Filters may have arguments. The syntax for this is

 {{ expression | filter:argument1:argument2:... }}

E.g. the markup {{ 1234 | number:2 }} formats the number 1234 with 2 decimal points using the number filter. The resulting value is 1,234.00.
In the above we have seen how we can create and use filters throughout the program. But in angular.js filter does not stop right there. We can also use them in controllers, services and also in directives.

Using filters in controllers, services, and directives:

For this, inject a dependency with the name <filterName>Filter to our controller/service/directive. E.g. using the dependency number Filter will inject the number filter. The injected argument is a function that takes the value to format as first argument and filter parameters starting with the second argument.
The example below uses the filter called filter. This filter reduces arrays into sub arrays based on conditions. In the demonstration below we have a shopping list, where value is hard-coded. We can chose the sorting type between name, price and quantity .
The example below therefore calls the filter directly in the controller. By this, the controller is able to call the filter only when needed (e.g. when the data is loaded from the back-end or the filter expression is changed).
Html file:

<div ng-app="app">
    <span class="bold">Demonstrating filtering and sorting using Angular JS</span>
    <br /><br />
        <div ng-controller="ShoppingCartCtrl">        
            <div>Sort by: 
            <select ng-model="sortExpression">
					<option value="Name">Name</option>
					<option value="Price">Price</option>
					<option value="Quantity">Quantity</option>
				</select>
            </div>
			<br />
			<div><strong>Filter Results</strong></div>
			<div> <input type="button" value="Apply " data-ng-click="applySortingAndFiltering()"></div>
                  <br />
            <table border="1">
				<thead>
					<tr>
						<th>Name</th>
						<th>Price</th>
						<th>Quantity</th>
					</tr>
				</thead>
				<tbody>
					<tr ng-repeat="item in items">
						<td>{{item.Name}}</td>
						<td>{{item.Price | rupee}}</td>
						<td>{{item.Quantity}}</td>
					</tr>
				</tbody>
                </table>
</div>
</div> 

Javascript file:

var app = angular.module('app', []);

app.controller('ShoppingCartCtrl', 
function ($scope, $filter, orderByFilter, filterFilter, rupeeFilter)  {
        var items = items = [
			{Name: "Soap", Price: 25, Quantity: 10},
			{Name: "Razor", Price: 50, Quantity: 15},
			{Name: "Shampoo", Price: 100, Quantity: 5},
            {Name: "Socks", Price: 75, Quantity: 10}
		];

        var calculateTotalPrice = function(){
            var price=0;
            for(i=0; i<$scope.items.length; i++){
                price += $scope.items[i].Price * $scope.items[i].Quantity;
            }
            $scope.totalPrice= $filter('rupee')(price);
        }

        $scope.items = items;
        calculateTotalPrice();

		$scope.mySortFunction = function(item) {
			if(isNaN(item[$scope.sortExpression]))
				return item[$scope.sortExpression];
			return parseInt(item[$scope.sortExpression]);
		}

        $scope.applySortingAndFiltering = function(){
            //$scope.items=$filter('filter')($filter('orderBy')(items,$scope.mySortFunction),$scope.search);
            $scope.items=filterFilter(orderByFilter(items, $scope.mySortFunction), $scope.search);
        }
});

app.filter('rupee', function(){
    return function(item){
        return "Rs. "+item;
    }
});

filter in angular.js

As we can see in the above demonstration that after selecting the option for sorting we have to fire the method by clicking apply button. The data in the table will get rearranged by the option we have selected.

Using filter in service:

The $filter service can be used to filter the data, it is declared along with the $scope service. let us create a simple example on $filter that will help us understand how to use the $filter service. In the below demonstration we will see a filter which acts on the given letter of the car and sorts.
Html file:

<form carid="form1" runat="server">
      <div ng-app="">
      <h1>Car Filter</h1>
        <div ng-controller="x">
          <input type="text" ng-model="search" />
          <table>
            <tbody>
              <tr ng-repeat="car in cars">
                <td>{{car.carId}}</td>
                <td>{{car.carName}}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </form> 

Javascript file:

function x($scope, $filter) {
            $scope.cars = [
                { carId: 001, carName: 'Santro' },
                { carId: 002, carName: 'i10 Grand' },
                { carId: 003, carName: '120' },
                { carId: 004, carName: 'Verna' },
                { carId: 005, carName: 'City' }];

            $scope.cars2 = $scope.cars;

            $scope.$watch('search', function (val) {
                $scope.cars = $filter('filter')($scope.cars2, val);
            });
        };

car

Creating custom filters:

Writing own filter is very easy: just register a new filter factory function with module. Internally, this uses the filterProvider. This factory function should return a new filter function which takes the input value as the first argument. Any filter arguments are passed in as additional arguments to the filter function.
Html file:

<div data-ng-controller="ClientCtrl">
    <ul class="inline">
        <li>
            <div class="alert alert-info">
                 <h4>Total Filtered Client: {{filtered.length}}</h4>

            </div>
        </li>
        <li>
            <div class="btn-group" data-ng-class="{open: open}">
                <button class="btn">Filter by Company</button>
                <button class="btn dropdown-toggle" data-ng-click="open=!open"><span class="caret"></span>

                </button>
                <ul class="dropdown-menu" aria-labelledby="dropdownMenu">
                    <li><a data-ng-click="checkAll()"><i class="icon-ok-sign"></i>  Check All</a>

                    </li>
                    <li><a data-ng-click="selectedCompany=[];"><i class="icon-remove-sign"></i>  Uncheck All</a>

                    </li>
                    <li class="divider"></li>
                    <li data-ng-repeat="company in companyList"> <a data-ng-click="setSelectedClient()">{{company.name}}<span data-ng-class="isChecked(company.id)"></span></a>

                    </li>
                </ul>
            </div>
        </li>
    </ul>
    <hr/>
     <h3>Clients Table:</h3>

    <table class="table table-hover table-striped">
        <thead>
            <tr>
                <th style="width:10%">#</th>
                <th style="width:20%">Name</th>
                <th style="width:40%">Designation</th>
                <th style="width:30%">Company</th>
            </tr>
        </thead>
        <tbody>
            <tr data-ng-repeat="client in filtered = (clients | companyFilter:selectedCompany)">
                <td>{{$index + 1}}</td>
                <td><em>{{client.name}}</em>

                </td>
                <td>{{client.designation}}</td>
                <td>{{client.company.name}}</td>
            </tr>
        </tbody>
    </table>
   </div> 

Javascript file:

'use strict';
var App = angular.module('clientApp', ['ngResource', 'App.filters']);
App.controller('ClientCtrl', ['$scope', function ($scope) {
    $scope.selectedCompany = [];
    $scope.companyList = [{
        id: 1,
        name: 'Apple'
    }, {
        id: 2,
        name: 'Facebook'
    }, {
        id: 3,
        name: 'Google'
    }];

    $scope.clients = [{
        name: 'John',
        designation: 'Software Engineer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }, {
        name: 'Steven',
        designation: 'Database Administrator',
        company: {
            id: 3,
            name: 'Google'
        }
    }, {
        name: 'Roy',
        designation: 'Designer',
        company: {
            id: 2,
            name: 'Facebook'
        }
    }, {
        name: 'Michael',
        designation: 'Front-End Developer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }, {
        name: 'Abhinav',
        designation: 'Network Engineer',
        company: {
            id: 3,
            name: 'Google'
        }
    }, {
        name: 'Sammy',
        designation: 'Internet Marketing Engineer',
        company: {
            id: 1,
            name: 'Apple'
        }
    }];

    $scope.setSelectedClient = function () {
        var id = this.company.id;
        if (_.contains($scope.selectedCompany, id)) {
            $scope.selectedCompany = _.without($scope.selectedCompany, id);
        } else {
            $scope.selectedCompany.push(id);
        }
        return false;
    };

    $scope.isChecked = function (id) {
        if (_.contains($scope.selectedCompany, id)) {
            return 'icon-ok pull-right';
        }
        return false;
    };

    $scope.checkAll = function () {
        $scope.selectedCompany = _.pluck($scope.companyList, 'id');
    };
}]);

angular.module('App.filters', []).filter('companyFilter', [function () {
    return function (clients, selectedCompany) {
        if (!angular.isUndefined(clients) && !angular.isUndefined(selectedCompany) && selectedCompany.length > 0) {
            var tempClients = [];
            angular.forEach(selectedCompany, function (id) {
                angular.forEach(clients, function (client) {
                    if (angular.equals(client.company.id, id)) {
                        tempClients.push(client);
                    }
                });
            });
            return tempClients;
        } else {
            return clients;
        }
    };
}]);

custom filter

In the above we have seen how to create filters and custom filters. How to use them. But still there are a lot of ways we can invoke a filter in our projects.

Related Links:
1>Directive in Angular.js – Part 1
2>Directive in Angular.js – Part 2
3>Working with Modules in Angular.js
4>Angular Router and UI-Router
5>Angularjs and Services
6>Angular.js Promise
7>Angular.js Two Way Data Binding
8>Angular Templates
9>Using Controllers in Angular.Js
10>Angularjs with Server Side Interaction
11>Working Through Angular.js With Transclude
12>Angular.js Event Handling

If you find this article helpful, you can connect us in Google+ and Twitter.

Filed in: Angular.js