[javascript] Angular.js ng-repeat filter by property having one of multiple values (OR of values)

Is it possible to filter an array of objects, such that the value of property can be either of a few values (OR condition) without writing a custom filter

This is similar to this problem - Angular.js ng-repeat :filter by single field

But instead of

<div ng-repeat="product in products | filter: { color: 'red' }">

is it possible to do something like this

<div ng-repeat="product in products | filter: { color: 'red'||'blue' }">

for a sample data as follows-

$scope.products = [
   { id: 1, name: 'test', color: 'red' },
   { id: 2, name: 'bob', color: 'blue' }
   /*... etc... */
];

I've unsuccessfully tried

<div ng-repeat="product in products | filter: { color: ('red'||'blue') }">

The answer is


Best way to do this is to use a function:

<div ng-repeat="product in products | filter: myFilter">

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

Alternatively, you can use ngHide or ngShow to dynamically show and hide elements based on a certain criteria.


I thing ng-if should work:

<div ng-repeat="product in products" ng-if="product.color === 'red' 
|| product.color === 'blue'">

Here is a way to do it while passing in an extra argument:

https://stackoverflow.com/a/17813797/4533488 (thanks to Denis Pshenov)

<div ng-repeat="group in groups">
    <li ng-repeat="friend in friends | filter:weDontLike(group.enemy.name)">
        <span>{{friend.name}}</span>
    <li>
</div>

With the backend:

$scope.weDontLike = function(name) {
    return function(friend) {
        return friend.name != name;
    }
}

.


And yet another way with an in-template filter only:

https://stackoverflow.com/a/12528093/4533488 (thanks to mikel)

<div ng:app>
  <div ng-controller="HelloCntl">
    <ul>
       <li ng-repeat="friend in friends | filter:{name:'!Adam'}">
            <span>{{friend.name}}</span>
            <span>{{friend.phone}}</span>
        </li>
    </ul>
</div>


After not able to find a good universal solution I made something of my own. I have not tested it for a very large list.

It takes care of nested keys,arrays or just about anything.

Here is the github and demo

app.filter('xf', function() {
    function keyfind(f, obj) {
        if (obj === undefined)
            return -1;
        else {
            var sf = f.split(".");
            if (sf.length <= 1) {
                return obj[sf[0]];
            } else {
                var newobj = obj[sf[0]];
                sf.splice(0, 1);
                return keyfind(sf.join("."), newobj)
            }
        }

    }
    return function(input, clause, fields) {
        var out = [];
        if (clause && clause.query && clause.query.length > 0) {
            clause.query = String(clause.query).toLowerCase();
            angular.forEach(input, function(cp) {
                for (var i = 0; i < fields.length; i++) {
                    var haystack = String(keyfind(fields[i], cp)).toLowerCase();
                    if (haystack.indexOf(clause.query) > -1) {
                        out.push(cp);
                        break;
                    }
                }
            })
        } else {
            angular.forEach(input, function(cp) {
                out.push(cp);
            })
        }
        return out;
    }

})

HTML

<input ng-model="search.query" type="text" placeholder="search by any property">
<div ng-repeat="product in products |  xf:search:['color','name']">
...
</div>

For me, it worked as given below:

<div ng-repeat="product in products | filter: { color: 'red'||'blue' }">

<div ng-repeat="product in products | filter: { color: 'red'} | filter: { color:'blue' }">

I found a more generic solution with the most angular-native solution I can think. Basically you can pass your own comparator to the default filterFilter function. Here's plunker as well.


In HTML:

<div ng-repeat="product in products | filter: colorFilter">

In Angular:

$scope.colorFilter = function (item) { 
  if (item.color === 'red' || item.color === 'blue') {
  return item;
 }
};

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature

Examples related to angularjs-ng-repeat

Angular ng-repeat add bootstrap row every 3 or 4 cols ng-if, not equal to? Understanding the ngRepeat 'track by' expression Calculating sum of repeated elements in AngularJS ng-repeat Angular.js ng-repeat filter by property having one of multiple values (OR of values) Using ng-if as a switch inside ng-repeat? In Angular, how to pass JSON object/array into directive? how to split the ng-repeat data with three columns using bootstrap Preserve line breaks in angularjs ng-repeat: access key and value for each object in array of objects

Examples related to angularjs-filter

Angular.js ng-repeat filter by property having one of multiple values (OR of values) Using AngularJS date filter with UTC date Limit the length of a string with AngularJS Descending order by date filter in AngularJs ng-repeat :filter by single field filters on ng-model in an input