1

So I have some code that looks like this:

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

<td ng-repeat="key in targets">
    {{ display_names[key] }}
</td>

To be more clear:

  • targets is a variable containing not-human readable ids such as key012

  • display_names is an object which has keys like: key012: "USA"


I would like to filter the display_names value from the search? Looking at the angularjs docs, I know I can filter key, but I haven't figured out how to filter display_names


Example

Here's a full example:

 var TS = angular.module('myapp', []);

 TS.controller('test', function($scope) {
   $scope.targets = ["id_1", "id_2"];
   $scope.display_names = {
     "id_1": "USA",
     "id_2": "Mexico"
   };
 });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="myapp" ng-controller="test">
  <input ng-model="search" placeholder="Search...">

  <ul>
    <li ng-repeat="key in targets">{{display_names[key]}}</li>
  </ul>
</body>
Downgoat
  • 13,771
  • 5
  • 46
  • 69

2 Answers2

2
<td ng-repeat="key in targets">
    <span ng-if="display_names[key].indexOf(search) > -1">{{ display_names[key] }}</span>
</td>

use ng-if, or you could also use ng-show. Differences here

This way, as you write in search (which should be in $scope.search) angular will refresh the ng-repeat values to show

If you want to search it case-insensitive, you could use toLowerCase() function before using indexOf

display_names[key].toLowerCase().indexOf(search) > -1
Community
  • 1
  • 1
Gonzalo.-
  • 12,512
  • 5
  • 50
  • 82
1

You can't use a filter | in the html because you don't have the value you want to filter against in the array you are iterating over. Instead you can use ng-if to show/hide the elements based on the search. Something like:

<div ng-repeat="key in targets" ng-if="!search || !!display_names[key].match(search)">
  {{ display_names[key] }}
</div>

The !! boolean cast is done because otherwise a new Regex object will be returned for the match which triggers a digest cycle which will return another new object and so on.

You also probably want to iterate over <tr> rather than <td>, and you need a <table> element for these elements to be allowed.

Example: http://plnkr.co/edit/qrpLKD9x4IBXowpIgnrf?p=preview


You could also write a custom filter for this, but it is a lot more work:

.filter('displayNames' function () {
  return function (key, names, search) {
    return !search || !!names[key].match(search);
  };
});

And use it like key in targets | displayNames:display_names:search

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405