4

I am trying to filter a list of items using an array of values. So far I've successfully been able to filter numerous fields in a table, but I haven't been able to filter using numerous values within one column of the table. This plunker shows this filter object being used

$scope.filters = {
   user:{
     name:"John"
   },
   status:{
     name: "Approved" 
   }
};

However, what I am trying to accomplish to generate a filtered list based off this filters object:

$scope.filters = {
  user:{
    name:"John"
  },
  status:{
    name: ["Approved", "For Review"] 
  }
};

Basically I want a list of all Johns whose status name is either "Approved" or "For Review".

Is it possible to accomplish this using Angular's "filter" filter, or is this a job for a custom filter?

1
  • 1
    I think this can be done only using a custom filter. I searched through the docs but could not find anywhere stating the use of two expression in a filter. So I think you should only use a custom filter for it. Commented Jul 27, 2015 at 11:09

3 Answers 3

3

You will need to use custom filter for this. Or you could also filter by status array separately from filtering by user name:

$scope.filtered = $filter('filter')($scope.users, {user: $scope.filters.user}).filter(function(user) {
    return $scope.filters.status.name.indexOf(user.status.name) > -1;
});

Demo: http://plnkr.co/edit/KcP6bLujFnxFPXrVRfUp?p=preview

Sign up to request clarification or add additional context in comments.

2 Comments

This is really great !
This looks like it'll do the trick for the time being. Evidently this functionality was fine in previous versions of angular, but on the upgrade to 1.3 it broke. github.com/angular/angular.js/…. Thanks for your help
2

I think a good approach is to encapsulate all filtering logic about a property into the filter itself, and name that filter by what it does. In this example you have two filters: by user, and by status. It just so happens that currently you are only filtering by one property for each of these filters: name, but in the future you may have multiple properties to filter by in user and status.

Considering the above I suggest the following two filters for your module:

app.filter('byStatus', function() {
  return function(items, filter) {
    var out = [];
    //status.name
    angular.forEach(items, function(item) {
      if (filter.name.constructor != Array) {
        if (filter.name == item.status.name) {
          out.push(item);
        }
      } else if (filter.name.indexOf(item.status.name) > -1) {
        out.push(item);
      }
    });
    return out;
  };
});
app.filter('byUser', function() {
  return function(items, value) {
    var out = [];
    //user.name
    angular.forEach(items, function(item) {
      if (item.user.name.indexOf(value.name) > -1) {
        out.push(item);
      }
    });
    return out;
  };
});

Plunker: http://plnkr.co/edit/g3ERmycps8Fg6trE1NfN?p=preview

There are two $filter calls but that's fine, I always encourage clarity of code over performance to start with.

1 Comment

This would be a very good solution, but the data I put in plunkr is only a small sample of the entire dataset. Ideally I can just filter against any field, rather than create bespoke filters for specific fields. However, I do like this approach for smaller and more static data. I'm going to implement this in another area of the application. Thanks
1

Html :-

<table id="searchTextResults">
  <tr><th>Name</th><th>Phone</th><th>Status</th></tr>
  <tr ng-repeat="friend in friends | filter: myFilter">
    <td>{{friend.user.name}}</td>
    <td>{{friend.phone}}</td>
    <td>{{friend.status.name}}</td>
  </tr>
</table>

Custom filter :-

$scope.myFilter = function (item) { 
    return item.status.name === 'For Review' || item.status.name === 'Approved'; 
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.