Shepherd
Shepherd

Reputation: 293

Angular 1.5.x - passing a variable to a built-in filter

I'm trying to filter data based on the select and input fields. Here is part of my code:

<select ng-change="students.changeValue(changeFilter)" ng-model="changeFilter">
    <option ng-selected="true" value="name">Name</option>
    <option value="age">Age</option>
</select>
<input ng-model="searchPhrase" />

name and age are example keys that I have. Here is my data generator structure:

<div ng-class="{breakLine: $index % 3 === 0}" 
     class="student-item col-md-4"
     ng-repeat="s in students.studentsList | filter:{searchFilter: searchPhrase}">

The searchFilter is supposed to be a key that is set from a variable but it doesn't work. If I make there something like: filter:{name: searchPhrase} then it works because I have such keys in my data structures.

Here is a part of the controller:

.controller('StudentsListCtrl', ['$scope', function($scope) {

    $scope.searchFilter = '';
    this.changeValue = function(val) {
       console.log(val);  ---> gives key or age on change
       $scope.searchFilter = val;
    }

So when I manually write e.g.: | filter:{name: searchPhrase} then it works. But when I pass 'name' (i.e. the key) in a variable like: | filter:{searchFilter: searchPhrase} then it's broken...

How can I fix this?

Upvotes: 0

Views: 42

Answers (2)

T.Gounelle
T.Gounelle

Reputation: 6033

You should use the last option described in filter documentation for the expression:

function(value, index, array): A predicate function can be used to write arbitrary filters. The function is called for each element of the array, with the element, its index, and the entire array itself as arguments.

In the controller, you define the predicate, e.g.

$scope.personFilter = function(person) {
   // return true if this person should be displayed
   // according to the defined filter
}

and use it in the ng-repeat filter, e.g.

<ul>
  <li ng-repeat="p in persons | filter:personFilter">{{p.name}} ({{p.age}})</li>
</ul>

See the plunker for a demo. Note I choose age as a string to simplify the predicate function. You can refine it according to your needs.

Upvotes: 1

Fabian Scheidt
Fabian Scheidt

Reputation: 392

Write a function in your $scope to generate the object that is passed to the filter:

$scope.getFilterObject = function() {
  var filterObject = {};
  filterObject[$scope.searchFilter] = $scope.searchPhrase;
  return filterObject;
}

Use it as the argument in the filter:

ng-repeat="s in students.studentsList | filter:getFilterObject()"

Upvotes: 1

Related Questions