Search code examples
javascriptangularjsloopsangularjs-filter

For loop through custom filter results


I have a list of applications, I have a custom filter for getting the unique values of a specified field. I ng-repeat out checkboxes for each of these unique values to filter a table.

I need to for loop using the values returned by the unique filter. This is so I can have a button which unchecks all of the checkboxes returned in the ng-repeat.

I have it working but it loops through ALL of the tables values (which is thousands) instead of just for the unique values.

Markup:

    <div ng-repeat="cat in applications | unique : 'Category'">
       <label>
           <input name="abc" type="checkbox" ng-model="$parent.FCategory[cat.Category]" ng-value="cat" ng-init="$parent.FCategory[cat.Category]=true">{{ cat.Category }}
       </label>
    </div>

    <input type="button" ng-click="uncheckAll()">Untick

JS, Unique Filter:

App.filter('unique', function () {
    return function (collection, keyname)
    {
        var output = [],
            keys = [];
        angular.forEach(collection, function (item) {
            var key = item[keyname];
            if (keys.indexOf(key) === -1) {
                keys.push(key);
                output.push(item);
            }
        });
        return output;
    };
});

JS, uncheck all function:

 $scope.uncheckAll = function () {
        for (var i = 0; i < $scope.applications.length; i++) {
            var item = $scope.applications[i].Category;
           $scope.FCategory[item] = false;

        }
    };

The issue is 'for (var i = 0; i < $scope.applications.length; i++) {' loops for every single record, I can't figure out how to have '$scope.applications.length' only be for the unique filter results.

The best I can come up with (which doesn't work) is...

$scope.uncheckAll = function () {
        var a = $scope.applications;

        for (var i = 0; i < $filter('unique')(a,'Category').length; i++) {
            var item = $scope.applications[i].Category;
           $scope.FCategory[item] = false;

        }
    };

Solution

  • One way you could solve this, is to store the filtered results in a new scope variable (uniqueApplications), which is then passed into your uncheckAll function:

    <div ng-repeat="cat in (uniqueApplications = (applications | unique : 'Category'))">
       <label>
           <input name="abc" type="checkbox" ng-model="$parent.FCategory[cat.Category]" ng-value="cat" ng-init="$parent.FCategory[cat.Category]=true">{{ cat.Category }}
       </label>
    </div>
    
    <input type="button" ng-click="uncheckAll(uniqueApplications)">
    

    You also need to modify your uncheckAll function:

    $scope.uncheckAll = function (list) {
        for (var i = 0; i < list.length; i++) {
            var item = list[i].Category;
           $scope.FCategory[item] = false;
    
        }
    };