Search code examples
javascriptangularjsangular-filters

Angular filter based on dynamic list of IDs


In my Angular app, I want to filter the items generated on a dropdown button with ng-repeat based on a list of IDs that I already generate dynamically.

This list is basically an array of numbers that gets updated dynamically with $scope.$watchCollection, e.g.:

$scope.selectedBPs = [1, 2]

Each item I generate with ng-repeat on the aforementioned dropdwon button has an id property. What I want the filter to do, is to only show a specific item if $scope.selectedBPs contains its id.

Currently my HTML is:

<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
    <li ng-repeat="marker in vm.markers" ng-click="progressMarkerSelected.name = marker.name;">
        <a href role="menuitem" tabindex="-1">{{marker.name}}</a>
    </li>
</ul>

So basically, I only want the marker to appear if $scope.selectedBPs.indexOf(marker.bpId) > -1 (bpId being the item's id).

Is it possible to do this with a filter?

How do I pass $scope.selectedBPs to an angular filter, so that the dropdown list also gets updated dynamically whenever the list changes?


Solution

  • You can create your own custom filter in Angular, which can do anything you want, the syntax is simple, eg: ng-repeat="marker in vm.markers | filter : myAmazingFilter".

    In this custom filter you will receive your iterable item as argument, so you can do your test to show or not.

    See this example below:

    var app = angular.module("app", []);
    
    app.controller('ListCtrl', function($scope){
     
      $scope.cars = [
        {
          id: 1,
          'name': 'Mustang'
        },
        {
          id: 2,
          'name': 'Corvette'
        },
        {
          id: 3,
          'name': 'Camaro'
        },
        {
          id: 4,
          'name': 'Ford GT'
        }
      ];
      
      $scope.selectedIDs = [1,3];
      
      $scope.myCustomFilter = function(item){
        
        if ($scope.selectedIDs.indexOf(item.id) >= 0){ //Return true if item.id is Mustang or Camaro
          
          return true; //Return true to show your item in repeat
          
        }
        
        return false;
        
      }
     
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    
    <div ng-app="app">
      <div ng-controller="ListCtrl">
      
        <ul ng-repeat="car in cars | filter: myCustomFilter">
          <li>{{car.name}}</li>
        </ul>
        
      </div>
    </div>