jhamm
jhamm

Reputation: 25062

How to search on the displayed data and not the backing data using Angular

I am using ng-repeat to create a table of data:

<div class="divTable" ng-repeat="expense in exp.expenses | filter:exp.query">
    <div>{{expense.amount | ldCurrency : true}}</div>
     ...
</div>

A couple of the cells that I am creating are being modified through an Angular filter. In the example above, I am changing the integer to a currency. So the original 4 is changed to $4.00. When I filter the entire list with my exp.query, it does not modify the exp.query search term through the ldCurrency.

The means that if I search on $4, it will not find it, because the backing data is 4, even though $4 is on the page.

I know this is confusing, with the two types of filters that I am talking about here.

How can I search on the data that is being shown on the page and not on the backing data?

Upvotes: 0

Views: 81

Answers (1)

Victor Aguilar
Victor Aguilar

Reputation: 455

You have to create you own filter. What you want to do to is a bad idea, because you are melding the view layer and the model layer.

A example of a filter.

The html:

<input ng-model="query" ng-trim="true">
<span>Finding: </span><span>{{ query }}</span>
<div ng-repeat="product in products | productsFilter: query">
  <strong>{{ $index }}</strong>
  <span>{{ product.name }}</span>
  <span>{{ product.price | currency: '$'}}</span>
</div>

The custom filter:

.filter('productsFilter', [function () {

  // Private function: It removes the dollar sign.
  var clearQuery = function (dirtyQuery) {

    var index = dirtyQuery.indexOf('$');

    if (index === -1) 
      return dirtyQuery; 

    return dirtyQuery.substr(index+1, dirtyQuery.length-index)
  };

  // The Custom filter
  return function (products, query) {

    if (query === '') return products;

    var newProducts = [];

    angular.forEach(products, function (product) {

      var cleanQuery       = clearQuery(query);
      var strProductPrice  = '' + product.price;
      var index            = strProductPrice.indexOf(cleanQuery);

      if (index !== -1) {
        newProducts.push(product); 
      }
    });

    return newProducts;
  };
}]);

The key is in the angular.forEach. There I decide if the product will belong to the new filtered collection. Here you can do the match you want.

You can find the complete example in full plucker example and see a lot of filters in the a8m's angular-filter

Upvotes: 1

Related Questions