Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ng-repeat and filter, how to tell which items are visible?

I have an array of objects that I'm displaying in my Angular app using ng-repeat. I'm filtering out items using filter and the value of a search input. It works as expected. But, I have a "select all" / "deselect all" option and I only want to select the visibile items in the list (the ones that meet the current search criteria).

Without performing the same logic in my controller (i.e. using indexOf the search value on each of my objects), how can I tell which items are currently filtered out by ng-repeat/filter?

My view:

<input type="text" ng-model="searchValue">
<input type="checkbox" ng-model="checkAll" ng-change="toggleAll()">

<tr ng-repeat="item in items | filter:searchValue">
    <td>{{item.id}}</td>
    <td>{{item.name}}</td>
</tr>

A function in my controller:

$scope.toggleAll() {
     for(var i in $scope.items){
         // how can I tell if this item is filtered out in the view?
     }
}

I have significantly simplified my code samples here for simplicity since this question doesn't need much more detail. Is there a way to do what I'm thinking or do I need to perform the "search" again?

like image 534
amlyhamm Avatar asked Jun 08 '15 20:06

amlyhamm


2 Answers

You can bind the filtered array to another scope variable in your view, then access that in your controller.

View:

<tr ng-repeat="item in filteredItems = (items | filter:searchValue)">
  ...
</tr>

Controller:

$scope.toggleAll = function () {
  angular.forEach($scope.filteredItems, function (item) {
    // do stuff
  })
}
like image 108
azium Avatar answered Oct 12 '22 13:10

azium


Your issue is that ng-repeat is scope isolated. As a result you can't refer to the internal list that is being managed by ng-repeat from your controller/directive.

As a result there are 2 options

  1. Bind the filtered list to ng-repeat from your controller/directive, so you maintain the filtered list.

    //in your controller
    $scope.filteredItems = $filter('yourFilter')($scope.items,$scope.searchText);
    $scope.$watch('searchText', function(newValue){
       $scope.filteredItems = $filter('yourFilter')($scope.items, newValue);
    });
    
    //in your view
    <tr ng-repeat="item in filteredItems">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
    </tr>
    
  2. Perform the filter again in your controller/directive

    $scope.toggleAll() {
        var items = $filter('yourFilter')($scope.items, $scope.searchText);
        for(var i in items){
           //set your selected property
        }
    }
    
like image 21
mikeswright49 Avatar answered Oct 12 '22 11:10

mikeswright49