ca9163d9
ca9163d9

Reputation: 29159

AngularJs filter with "or" condition?

The code is available here: https://plnkr.co/edit/gbbsEnXxVpLsxvtKsDxw?p=preview. The filter filter: { a : 'x' } works and only one row is shown.

Question:

  1. It seems filter: { a : 'xxx' } matches any text in a as long as the text contains the string xxx. What if I want to do exact matching?
  2. How to implement: show all the rows if a = 'xxx' or b = 3 not not use c?
  3. Maybe it's better to use javascript code on `model.dashbardRows?

dashboard.component.js

(function () {
    'use strict';
    angular.module('testModule', []) 
    .component('dashboard', {
      templateUrl: 'dashboard.component.html',
      controllerAs: 'model',
      controller: [controller] 
    });

    function controller() {
      var model = this;
      model.dashboardRows = [
        {a:'xxx', b:1, c:'ss'}, 
        {a:'yyy', b:2, c:'tt'}, 
        {a:'zzz', b:3, c:'uu'}];
    }
})();

dashboard.component.html

<div>
  Test
  <table>
    <tr ng-repeat="i in model.dashboardRows | filter: { a : 'x' }">
      <td>{{i.a}}</td>
      <td>{{i.b}}</td>
    </tr>
  </table>
</div>

Upvotes: 1

Views: 9768

Answers (3)

Abhijeet
Abhijeet

Reputation: 8771

As suggested by @Valery using custom Filter is the best solution around this.

Here is fork using custom filter(multiple conditions)

dashboard.component.js

.filter("optionalFilter",function(){
  //console.log("filter loads");
  return function(items, firstArgument,secondArgument){
    //console.log("item is ",items); // it is value upon which you have to filter
    //console.log("firstArgument is ",firstArgument);
    //console.log("secondArgument ",secondArgument);
    var filtered = [];
    angular.forEach(items, function(value, key) {
      //console.log("val ::",value);
      if(value.a == firstArgument || value.b == secondArgument){
       // console.log("val ::",value.a);
        this.push(value);
      }
    }, filtered);
    //console.log("val ::",filtered);
    return filtered;
  }

dashboard.component.html

   <tr ng-repeat="i in model.dashboardRows | optionalFilter:'aaa':2">

Useful references:

Upvotes: 4

Valery Kozlov
Valery Kozlov

Reputation: 1577

I think you should use custom filter

module.filter('myFilter', function(){
   return function(input){
      return input.filter(yourFilterFn);
   };
});

ng-repeat="item in items | myFilter"

Upvotes: 1

Akos Lukacs
Akos Lukacs

Reputation: 2047

Take a look at the filter filter docs, you can pass in an optional comparator parameter.

true: A shorthand for function(actual, expected) { return angular.equals(actual, expected)}. This is essentially strict comparison of expected and actual.

Note that this is case sensitive (as string comparsion is case sensitive in JS).

Also there is an example too at he bottom of the page that demonstrates filtering all or only a single property. If your filtering is complex, or your source data is big, filtering in controller can help readability and performance too.

Upvotes: 2

Related Questions