Tuesday, July 22, 2014

AngularJS for Beginners: Custom Filter

Filter
Angular filters provide a way to format the data that we display to the user or we use in our app. There are several built-in filters. We can also create filter of our own.

How to create custom filter
We use Angular module’s filter method to create custom filter. It is best practice to create a separate module for declaring the filters. Let's create a simple filter to capitalize all the characters of a string.
 var myFilters = angular.module('myApp.filters', []);  
 myFilters.filter('makeUppercase', function () {  
      return function (input) {  
           if (input) {  
                return item.toUpperCase();  
           }  
      };  
 });  
Filter is basically a kind of function to which we pass single or multiple inputs. In the above example, we take a single input string. Filtering operations are applied on the input.

Using a consecutive filter method, we can create another filter. Let's create another filter to replace space characters with underscores.
 var myFilters = angular.module('myApp.filters', []);  
 myFilters.filter('makeUppercase', function () {  
      return function (input) {  
           if (input) {  
                return item.toUpperCase();  
           }  
      };  
 })  
 .filter('underscore', function () {  
      return function (input) {  
           if (input) {  
                return input.toLowerCase().replace(/[^a-z_]/g, '_');  
           }  
      };  
 });  

How to invoke
Filters can be invoked from either HTML or JavaScript. In HTML, filters are invoked by using the pipe ( | ) character inside the template binding characters {{ }}. Multiple filters can be applied to same expression. We can apply the 'makeUppercase' filter in the following way:
      {{ book.name | makeUppercase }}  
Applying both 'makeUppercase' and 'underscore' filters, the expression will look like the following:
      {{ book.name | underscore | makeUppercase }}  
Filters can be used from JavaScript by using the $filter service. We have to inject $filter as a dependency into our controller in order to invoke our filter. At the time of calling the filter, we can pass both the filter name and data as arguments. The following example shows how 'makeUppercase' and 'underscore' filters can be used from JavaScript:
 myModule.controller('BooksController',   
      function BooksController($scope, $filter) {  
           var bookname = 'The Mother';  
           var bookname = $filter('underscore')(bookname);       
           $scope.bookName = $filter('makeUppercase')(bookname);                 
      }  
 );  

Complete example
Here is the complete example:
 <!DOCTYPE html>  
 <html ng-app="myModule">  
 <head>  
    <title>Learning AngularJS</title>  
    <script src="angular.min.js"></script>  
 </head>  
 <body>  
      <div ng-controller="BooksController">  
           <br>  
           List of books:  
           <br>                  
           <ul>  
                <li ng-repeat="book in bookList">  
                     {{book.name | underscore | makeUppercase }}   
                     -- {{book.author}}   
                </li>  
           </ul>  
           Book name: <input type="text" ng-model="bookName" />  
           Author: <input type="text" ng-model="bookAuthor" /> <br>  
           <button ng-click="add()">Add</button>  
      </div>  
        
      <script>        
           var myFilters = angular.module('myApp.filters', []);  
           myFilters.filter('makeUppercase', function () {  
                return function (input) {  
                     if (input) {  
                          return input.toUpperCase();  
                     }  
                };  
           })  
           .filter('underscore', function () {  
                return function (input) {  
                     var inputLower = input.toLowerCase();  
                     return inputLower.replace(/[^a-z_]/g, '_');                      
                };  
           });  
                       
           var myModule = angular.module('myModule', ['myApp.filters']);       
           myModule.controller('BooksController',   
           function BooksController($scope) {  
                $scope.bookList = [  
                     {name:'The Tempest',   
                          author:'William Shakespeare'},  
                     {name:'Gitanjali',   
                          author:'Rabindranath Tagore'},  
                     {name:'Harry Potter',   
                          author:'J. K. Rowling'},  
                     {name:'The Da Vinci Code',   
                          author:'Dan Brown'},  
                     {name:'A Brief History of Time',   
                          author:'Stephen Hawking'},  
                     {name:'Tell Me Your Dreams',   
                          author:'Sidney Sheldon'}  
                ];  
                  
                $scope.add = function() {  
                     $scope.bookList.push({   
                          name: $scope.bookName,   
                          author: $scope.bookAuthor   
                     });  
                };  
           });       
       </script>  
 </body>  
 </html>  
We should see something like the following in the browser: