Question

I'm new in angular . i managed to filter using angular and it work fine but now i want to move filter outside of the controller which is quite challenging for me .

here is my html page :

<div >

    <input type="checkbox" ng-click="itemType('CAR')"/> CAR


    <input type="checkbox" ng-click="itemType('BIKE')"/> BIKE


    <input type="checkbox" ng-click="itemType('CYCLE')"/> CYCLE

</div>  
<table>
   <tbody>
          <tr ng-repeat="item in items | filter:filterItem">
            <td >{{item.name}}</td>
            <td >{{item.type}}</td>
          </tr>
    </tbody>
</table>

and controller :

app.controller('MainCtrl', function($scope) {

 $scope.items = [
    {name: 'bmw', type:'CAR' },
    {name: 'ducati',type:'BIKE'},
    {name: 'airbas',type:'CYCLE' }
   ];

$scope.typeArray = [];
$scope.itemType = function(type) {
var i = $.inArray(type, $scope.typeArray);
if (i > -1) {
  $scope.typeArray.splice(i, 1);
} else {
  $scope.typeArray.push(type);
}
}

$scope.filterItem = function(item) {
if ($scope.typeArray.length > 0) {
  if ($.inArray(item.type, $scope.typeArray) < 0){
    return false;
  }
}
return item;
}
});

how can i move filtering from controller to app.filter(). Thanks.

Was it helpful?

Solution

Yes, the custom filter is a separate module and you can write it as:

iApp.filter('myfilter', function() {
   return function( items, types) {
    var filtered = [];

    var looping = function(name){
      angular.forEach(items, function(item) {
         if(item.type === name){
             filtered.push(item);
           }
        });
    }

      if(types.car == true){
        looping('CAR');
      }
      if(types.bike == true){
        looping('BIKE');
      }
      if(types.cycle == true){
        looping('CYCLE');
      }


    return filtered;
  };
});

Controller:

$scope.types = {car: false, bike:false, cycle: false};

   $scope.items = [
    {name: 'bmw', type:'CAR' },
    {name: 'ducati',type:'BIKE'},
    {name: 'airbas',type:'CYCLE' }
   ];

Demo 1 Plunker

[EDIT]

If you want to show all cells when no checkbox is selected, add this to filter:

  var flag = true;
  angular.forEach(types, function(type){
    flag = flag & !type; // if one of flags will be false, we get flag=false
  });

  if(flag == true){
    return items;
  }

Demo 2 Plunker

FYI: You can see that filters do not use $scope. If you want to pass additional argument the syntax should be:

 <tr ng-repeat="item in items | filter:myfilter:types">

where types is some object

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top