0

I have items to search by title(string) or tags(array of strings)

items:

[
  {
    title: 'My title',
    tags: ['tag1', 'other']
  },
  {
    title: 'Misc',
    tags: ['tag1', 'notag']
  }
]

I want one input to search in title OR tags

In my template, this works well :

<form>
    <input type="text" ng-model="query">
</form>

<li ng-repeat="item in items | filter:query:title | filter:query:tags">
    <p>{{item.title}}</p>
</li>

All my items are shown and if I enter text, it filter by title or tags. ex: I type title, only the first item is returned and if I type tag1, both are returned.

Now, I need to have an other scope with the results of that search filter.

In my controller/directive, I tryied :

scope.filteredItems = $filter('filter')($filter('filter')(scope.items, {title: scope.query}), {tags: scope.query});

But I don't have the same results, what did I miss?

Tib
  • 2,553
  • 1
  • 27
  • 46

1 Answers1

1

First of all, you are using the filter incorrectly in your HTML. If you look at the filter documentation, you will see that it expects an expression and a comparator. So, as of right now, in the HTML, you are passing query as the expression and title or tags as the comparator, both of which are undefined.

Because you are passing a string as the expression,

The string is evaluated as an expression and the resulting value is used for substring match against the contents of the array. All strings or objects with string properties in array that contain this string will be returned.

In other words, all of the properties in each item are searched for the query. This is why it seems to be filtering by title and/or tags.

Then, in your controller, you are passing an object as the expression. This makes it so it does in fact only return items where the given attribute matches the given value. However, since you're invoking it twice, you are filtering your items where BOTH title and tags match your query.

There are two ways to go about fixing this.

If you don't mind searching all fields for query, you can do this as follows. In your HTML, replace with

<li ng-repeat="item in items | filter:query">

and in your controller, replace with

$scope.filteredItems = $filter("filter")($scope.items, $scope.query);

However, if you'd like to only search title and tags, it's a lot more complicated. See this post on how to create a custom filter that searches multiple fields:

How to filter multiple values (OR operation) in angularJS

Community
  • 1
  • 1
Lukas
  • 9,765
  • 2
  • 37
  • 45
  • But how about if the OP _only_ wants to filter on `title` and `tags`? – Davin Tryon Mar 04 '14 at 14:35
  • Thanks for your answer :) and yes, I want to filter only on title and tags. Is there any way to keep the default angular filter with only specific values? – Tib Mar 04 '14 at 17:02
  • Unfortunately, the default angular filter only lets you filter on ALL values you specify, not some. – Lukas Mar 04 '14 at 17:57