oded
oded

Reputation: 179

How to check filtered checkboxs only in AngularJS in select all checboxes?

I have this angular table:

$scope.customers = [{
  first_name: "Oded",
  last_name: "Taizi",
  id: 1,
  type_link: 2
}, {
  first_name: "Ploni",
  last_name: "Almoni",
  id: 2,
  type_link: 2
}, {
  first_name: "Fred",
  last_name: "Dyllan",
  id: 3,
  type_link: 2
}, {
  first_name: "Dan",
  last_name: "Omer",
  id: 4,
  type_link: 4
}, {
  first_name: "Amir",
  last_name: "Maly",
  id: 5,
  type_link: 3
}, {
  first_name: "Noa",
  last_name: "Levy",
  id: 6,
  type_link: 3
}];

And this function:

 $scope.checkAll = function(isCheck) {
    angular.forEach($scope.customers, function(cust) {
      cust.select = isCheck.selectAll;
    });
 };

And I want to filter this data by free search and by group. This is working for me.
My problem is when clicking the select all checkbox, it selects all the checkboxes even when filtered

I only want to check all the filtered rows.

Here is my jsfiddle.
Try to filter by the select box.

Upvotes: 2

Views: 63

Answers (3)

tanmay
tanmay

Reputation: 7911

You can have a reference to your filtered array:

<tr ng-repeat="cust in filteredCustomers = (customers | orderBy:orderByField:reverseSort | 
    filter :searchInput | filter: {type_link: typesModel}) ">

which would be accessible directly as $scope.filteredCustomers.

Now, instead of all the customers, check only the ones from $scope.filteredCustomers. Like:

$scope.checkAll = function(isCheck) {
  angular.forEach($scope.filteredCustomers, function(cust) {
    cust.select = isCheck.selectAll;
  });
};

working fiddle | fiddle with $scope.filteredCustomers

Upvotes: 1

andreim
andreim

Reputation: 3503

You can also replicate the logic using filters.

Inject the $filter service into your controller constructor like:

app.controller('myCtrl', function($scope,$http,$filter){ ... });

Then you can use $filter('<filter_name>') in order to get the corresponding filter:

  $scope.checkAll = function(isCheck) {
        let customersBySearchInput = $filter('filter')($scope.customers, $scope.searchInput);
        let customersBySearchInputAndType = $filter('filter')(customersBySearchInput, {type_link: $scope.typesModel});

        angular.forEach(customersBySearchInputAndType, function(cust) {
          cust.select = isCheck.selectAll;
        });
     };

Having the same logic in multiple places would not be a good idea. Therefore you could create a function in your controller which does the filtering then that can be reused in your template and other functions.

NOTE: don't forget about testability - usually is better to reduce the amount of code complexity in your template and provide controller methods that does the business or that delegates the concern to another service. Regarding testability, this would improve as you can easily unit test your controller logic and increase your code coverage.

Upvotes: 0

Mistalis
Mistalis

Reputation: 18269

Why don't you just set the value when checking to $scope.selectAll`?

$scope.checkAll = function() {
    angular.forEach($scope.customers, function(cust) {
      cust.select = $scope.selectAll;
    });
};

Forked your Fiddle here

As a side note, you can also change the checkbox of each customer to something like:

<input type="checkbox" ng-model="cust.select" ng-click="cust.select = !cust.select">

Upvotes: 0

Related Questions