Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic filter within ng-repeat in AngularJS

For my AngularJS app I have an ng-repeat in an ng-repeat like so:

Html:

<div ng-app="myApp">
    <div ng-controller="myController">
        <h2>working filter</h2>
        <div ng-repeat="category in categories">
            <h3>{{category}}</h3>
            <div ng-repeat="item in items | filter:{price.red: 0} ">{{item.name}}</div>
    </div>

        <h2>broken filter</h2>
        <div ng-repeat="category in categories">
            <h3>{{category}}</h3>
            <!-- price[category] should be red, blue, yellow, depending on the category in the ng-repeat -->
            <!-- price[category] should be bigger then 0 (or not zero, negative values will not occur) -->
            <div ng-repeat="item in items | filter:{price[category]: 0} ">{{item.name}}</div>
        </div>

    </div>
</div>

Javascript:

var myApp = angular.module('myApp', []);

myApp.controller('myController', function ($scope) {

    $scope.categories = ['red', 'blue', 'yellow'];
    $scope.items = [
        {name: 'one', price:{red: 0, blue: 1, yellow: 3} },
        {name: 'two', price:{red: 2, blue: 0, yellow: 0}},
    ]    

});

Please see my jsFiddle http://jsfiddle.net/hm8qD/

So I ran into two problems:

  1. The flter does not accept [] brackets so I cannot make the filter dynamic, based on the category
  2. The filter needs to return items that have a price[category] greater then zero.

For the greater then zero I could just make a custom filter. However as far as I know filters don't accept parameters so I have no way of getting the category (red, blue or yellow) to it.

Please note this is an simplified version of my actual code and this context might not make the best of sense. I hope I was clear in explaining what I need the filter to do, since I'm new to AngularJS.

like image 420
DivZero Avatar asked May 17 '13 11:05

DivZero


1 Answers

Apparently it is actually possible to pass arguments to your filter, but you have to make a custom filter instead of using "filter: expression". What I did was create a custom filter which takes the items and category as arguments and returns the array with filtered items.

myApp.filter('myFilter', function () {
    return function (items, category) {
        var newItems = [];
        for (var i = 0; i < items.length; i++) {
            if (items[i].price[category] > 0) {
                newItems.push(items[i]);
            }
        };

        return newItems;
    }
});

See the updated Fiddle here: http://jsfiddle.net/hm8qD/3/  

like image 114
DivZero Avatar answered Oct 20 '22 15:10

DivZero