0

If i have a json array containing my products and am using ng-repeat to display them on page.

I then have two select boxes used to filter by colour and size which is all working fine,

However if I filter by colour the size select box still shows all sizes for the entire array of products, how can I refresh the contents of the size select box based on whats filtered?

2 Answers 2

2

Cant figure out how to reply to previous thread, sorry :) Here is a modified fiddle: http://jsfiddle.net/q7EkY/7/

$scope.color = '';
$scope.size = '';
$scope.colors = function () {
    var colors = [];
    for (var i = 0; i < $scope.items.length; i++) {
       if (colors.indexOf($scope.items[i].colour) == -1) colors.push($scope.items[i].colour);
    }
    return colors;
};

$scope.sizes = function () {
    var sizes = [];
    for (var i = 0; i < $scope.items.length; i++) {
       if ((!$scope.color || $scope.items[i].colour == $scope.color) && sizes.indexOf($scope.items[i].size) == -1) sizes.push($scope.items[i].size);
    }
    return sizes;
}

$scope.doFilter = function () {
    var filter = {};
    if ($scope.color) filter.colour = $scope.color;
    if ($scope.size) filter.size = $scope.size;
    return filter;
}

Template:

<div ng-controller="myCtrl">
    <select ng-model="color" ng-options="c for c in colors()">
        <option value="">Colour</option>
    </select>
    <select ng-model="size" ng-options="s for s in sizes()">
        <option value="">Size</option>
    </select>
    <div ng-repeat="item in items | filter:by_colour | filter:doFilter()">
        {{ item.title }}
    </div>
</div>

I think there should be more clear way to filter values, using _.js, for example.

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

5 Comments

Perfect thanks, I'm actually using code $scope.uniqueColours = function() { return _.chain($scope.products) .pluck('colour_title') .flatten() .unique() .value(); }; to get my unique colours but your fiddle is exactly what I'm looking for.
@Pythonic, you can "edit" your posts. Just put Update or something in it to make it obvious that it has been updated/changed.
@Pythonic, is it possible to do the same thing if size in the items array is also an array, so each product can have more than one size?
You just have to modify doFilter() and sizes() code, to itterate over size, if it as an array, and check if size persists here.
Just modified an example, cause i may be not clear, how to filter that data. You need to filter another way, using a filter function, not passing an object. jsfiddle.net/q7EkY/10
1

You should create a filter function in your scope, and use it as an argument of "a | filter" Here is a short example of using this:

View:

<div ng-controller="myCtrl">
<div ng-repeat="item in items | filter:doFilter()">
    {{ item.title }}
</div>
<div>Is filter active? <input type="checkbox" ng-model="filterActive"/></div>

Controller:

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

myApp.controller('myCtrl', function ($scope) {
    $scope.items = [{
        title: 'First item',
        active: true
    }, {
        title: 'Second item',
        active: false
    }];
    $scope.doFilter = function () {
        if ($scope.filterActive) return { active: true };
        return {};
    }
});

http://jsfiddle.net/q7EkY/1/

1 Comment

Thanks @Pythonic, I've updated the fiddle slightly to include the two select boxes. How do i apply the doFilter() method so that when I filter by red, then only one size shows in the size select box?

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.