Mr.Web
Mr.Web

Reputation: 7156

AngularJS, filter only if a variable is true

I have an ng-repeat with many filters.

(1) From an input field:

<input type="text" ng-model="search">

(2) Another one from a list of buttons:

<ul id="element_filter" class="uk-subnav uk-subnav-pill uk-margin-remove">
    <li ng-class="statusFilter == '' ? 'uk-active' : ''"><a ng-click="statusFilter = ''">Tutti</a></li>
    <li ng-class="statusFilter == '1' ? 'uk-active' : ''"><a ng-click="statusFilter = '1'">Nuovo</a></li>
</ul>

Connected to a custom filter named filtraStato

(3) Than I have a checkbox:

<div class="uk-width-medium-1-6">
    <input type="checkbox" name="checkbox_demo_inline" id="checkbox_mostra_zone" ng-model="openFiltraZone" data-md-icheck />
    <label for="checkbox_mostra_zone" class="inline-label">Filtra Zone</label>
</div>

This is also connected to a custom filter filtraZona

I then have an ng-repeat where the filter filtraZona should be active only if the checkbox openFiltraZone is checked.

I don't know what to put on the repeater expression in order to apply the filter only if openFiltraZone is checked

<tr ng-repeat="cliente in clienti | filter:search | filtraStato:statusFilter | filtraZona:zonaFilter">

Upvotes: 3

Views: 2720

Answers (3)

kwerle
kwerle

Reputation: 2401

A little late to the party, but this works for me with angular 1.x:

| filter:{other filters, active: (active ? true : "")}

Upvotes: 2

rzelek
rzelek

Reputation: 4023

I think that the only way is to write custom filter function for that, like this:

In controller/directive:

var _filter = $filter('filtraZona');
$scope.filterFnc = function(elem) {
  if(!$scope.openFiltraZone) return true; //leave on list when openFiltraZone is not checked
  return _filter([elem], $scope.zonaFilter).length > 0; //this will get filtraZona filter and apply it to one element array (created with [elem] expression) with $scope.zonaFilter parameter. Whole expression will return true only if filtraZona will not filter out elem.
}

In view:

<tr ng-repeat="cliente in clienti | filter:search | filtraStato:statusFilter | filter:filterFnc">

I believe that this is the only way if you do not want to change filtraZona filter. Please notice, that this is not the most cpu-efficient way.

If you can change filtraZona implementation, you can add simple pre-check to it's code:

angular.filter('filtraZona', function() {
  return function(arr, param1, checkboxChecked) {
    var arr2 = [];
    angular.forEach(arr, function(elem) {
      if(!checkboxChecked) arr2.push(elem);
      //rest of filtraZona logic goes here
    });
    return arr2;
  };
});

And use it this way (notice second parameter to filtraZona):

<tr ng-repeat="cliente in clienti | filter:search | filtraStato:statusFilter | filtraZona:zonaFilter:openFiltraZone">

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136184

You could simply have it like

item in items | filter: box ? search: ''"

Demo Plunkr

Upvotes: 4

Related Questions