Monday, July 21, 2014

AngularJs filter, creating a custom filter with custom parameters

(You might like this AngularJS Tutorial: ngtutorial.com/tutorial.html

AngularJs filters are one of the great features in angularjs. One day, you might need to use a custom filter and with great luck you found this blog!

Here is how the custom filter would look like (note on the myfilter):
 <tr ng-repeat="friend in friends |myfilter:'param1':'param2':true:'windowScopedFilter'">  

Our custom filter will be named "myfilter", it will have 4 parameters separated by ':'.

Here is a sample input that we will be using:
   $scope.friends = [{name:'John', phone:'555-1276'},  
                      {name:'Annie', phone:'800-BIG-MARY'},  
                      {name:'Mike', phone:'555-4321'},  
                      {name:'Adam', phone:'555-5678'},  
                      {name:'David', phone:'555-8765'},  
                      {name:'Mikay', phone:'555-5678'}];  

Our filter will try to print only those that have "555" in their phone numbers, example output:
 Name     Phone  
 John      555-1276  
 Mike      555-4321  
 Adam      555-5678  
 David      555-8765  
 Mikay      555-5678  
The process that filters the "555" will be executed by "windowScopedFilter", the 4th parameter from our custom 'myfilter'.


Here is how we do it (adds logging to each input parameter):
 var myapp = angular.module('MyFilterApp', []);  
 myapp.filter('myfilter', function() {  
   return function(input, param1) {  
      console.log("------------------------------------------------- begin dump of custom parameters");  
      console.log("input=",input);  
      console.log("param1(string)=", param1);  
      var args = Array.prototype.slice.call(arguments);  
      console.log("arguments=", args.length);  
      if (3<=args.length) {  
           console.log("param2(string)=", args[2]);  
      }  
      if (4<=args.length) {  
           console.log("param3(bool)=", args[3]);  
      }  
      console.log("------------------------------------------------- end dump of custom parameters");  
      // filter  
      if (5<=args.length) {  
           return window[args[4]](input);  
      }  
      return input;  
   };  
 });  


The code above are mostly logging. The important part that really does the filtering is the:
      // filter  
      if (5<=args.length) {  
           return window[args[4]](input);  
      }  
      return input;  

"return window[args[4]](input)" invokes our 4th parameter, which is the 'windowScopedFilter'.

Here is a sample console output:
 "------------------------------------------------- begin dump of custom parameters" custom_filter_function.html:21  
 "input=" [object Array] custom_filter_function.html:22  
 "param1(string)=" "param1" custom_filter_function.html:23  
 "arguments=" 5 custom_filter_function.html:25  
 "param2(string)=" "param2" custom_filter_function.html:27  
 "param3(bool)=" true custom_filter_function.html:30  
 "------------------------------------------------- end dump of custom parameters" custom_filter_function.html:32  
 "------------------------------------------------- begin dump of custom parameters" custom_filter_function.html:21  
 "input=" [object Array] custom_filter_function.html:22  
 "param1(string)=" "param1" custom_filter_function.html:23  
 "arguments=" 5 custom_filter_function.html:25  
 "param2(string)=" "param2" custom_filter_function.html:27  
 "param3(bool)=" true custom_filter_function.html:30  
 "------------------------------------------------- end dump of custom parameters" custom_filter_function.html:32  

The complete code:
 <html>  
  <head>  
 <script src="angular.min.js"></script>  
 <script type="text/javascript">  
 function windowScopedFilter (input) {  
      var output = [];  
      angular.forEach(input, function(v,k){  
           if (v.phone.contains("555")) {  
                output.push(v);  
           }  
      });  
      return output;       
 }  
 var myapp = angular.module('MyFilterApp', []);  
 myapp.filter('myfilter', function() {  
   return function(input, param1) {  
      console.log("------------------------------------------------- begin dump of custom parameters");  
      console.log("input=",input);  
      console.log("param1(string)=", param1);  
      var args = Array.prototype.slice.call(arguments);  
      console.log("arguments=", args.length);  
      if (3<=args.length) {  
           console.log("param2(string)=", args[2]);  
      }  
      if (4<=args.length) {  
           console.log("param3(bool)=", args[3]);  
      }  
      console.log("------------------------------------------------- end dump of custom parameters");  
      // filter  
      if (5<=args.length) {  
           return window[args[4]](input);  
      }  
      return input;  
   };  
 });  
 myapp.controller('MyFilterController', ['$scope', function($scope) {  
   $scope.friends = [{name:'John', phone:'555-1276'},  
                      {name:'Annie', phone:'800-BIG-MARY'},  
                      {name:'Mike', phone:'555-4321'},  
                      {name:'Adam', phone:'555-5678'},  
                      {name:'David', phone:'555-8765'},  
                      {name:'Mikay', phone:'555-5678'}];  
 }]);  
 </script>  
 </head>  
 <body ng-app="MyFilterApp">  
 <div ng-controller="MyFilterController">  
      <table id="searchTextResults">  
       <tr><th>Name</th><th>Phone</th></tr>  
       <tr ng-repeat="friend in friends |myfilter:'param1':'param2':true:'windowScopedFilter'">  
        <td>{{friend.name}}</td>  
        <td>{{friend.phone}}</td>  
       </tr>  
      </table>  
 </div>  
 <hr>  
 </body>  
 </html>