1

I'm using ng-repeat to draw table lines and I'm currently filtering on multiple text parameters. Here is a simplified example with fixed strings

<tr ng-repeat="thisOffer in offerList | filter: {name: 'hotel', id: 'H2O_'}"></tr>

This works fine and now I want to filter also on a number, testing if it's lower than a given value. Is it possible to use a filter like the following ones? I can't find anything similar in angular documentation but I can't believe a straightforward solution doesn't exist

<tr ng-repeat="thisOffer in offerList | filter: {name: 'hotel', id: 'H2O_', number: '<5' }"></tr>
<tr ng-repeat="thisOffer in offerList | filter: {name: 'hotel', id: 'H2O_'} | filter: 'thisOffer.number < 5' "></tr>
Naigel
  • 9,086
  • 16
  • 65
  • 106

4 Answers4

3

After applying this answer, this fiddle work for you (inspired from this answer)

<div ng-app>
  <div ng-controller="TodoCtrl">
    <ul>
      <li ng-repeat="friend in friends | filter: {name: 'John'} | filter: greaterThan('phone', 1)">
        <span>{{friend.name}}</span>
        <span>{{friend.phone}}</span>
      </li>
    </ul>
  </div>
</div>
Community
  • 1
  • 1
asdf_enel_hak
  • 7,474
  • 5
  • 42
  • 84
  • It works, but it slows down incredibly the rendering. I fear the only way to accomplish this efficiently is using a custom `filter` :( – Naigel Mar 02 '16 at 15:30
  • For that it should dig into angular source code or even better ask in a question if "custom filter slows down?". But i "think" it does not – asdf_enel_hak Mar 02 '16 at 15:32
  • I can make an analogy that cost of assigment in a for loop, which is considered zero. – asdf_enel_hak Mar 02 '16 at 15:33
1

According to https://docs.angularjs.org/guide/filter you can chain filters, so your second solution should work.

If not, please provide a fiddle so I can look into it

Aides
  • 3,643
  • 5
  • 23
  • 39
  • when `filter` takes a string input it looks for a match, it doesn't execute the expression, so that can't work – Naigel Mar 02 '16 at 14:39
  • Ah ok, thought your question was about chaining filters, not how to set up a numeric filter. See http://stackoverflow.com/a/35749798/4068027 for a solution to that. – Aides Mar 02 '16 at 15:02
1

You would need to create a predicate function in the relevant scope, and use it in your ng-repeat, as in:

<tr ng-repeat="thisOffer in offerList | filter: lessThan('Number', 5)""></tr>
Vasan
  • 375
  • 1
  • 12
0

Create a function on the relevant scope:

$scope.greaterThan = function(prop, val){
    return function(item){
      return item[prop] > val;
    }
}

As a first argument, it takes a property name on the object. The second argument is an integer value.

Use it in your view like this:

<tr ng-repeat="thisOffer in offerList | filter: greaterThan('Number', 0)">
Surjeet Bhadauriya
  • 6,755
  • 3
  • 34
  • 52