ng-repeat :filter by single field
Asked Answered
A

12

500

I have an array of products that I'm repeating over using ng-repeat and am using

<div ng-repeat="product in products | filter:by_colour"> 

to filter these products by colour. The filter is working but if the product name / description etc contains the colour then the product remains after the filter is applied.

How do I set the filter to only apply to the colour field of my array rather than every field?

Arsenical answered 6/2, 2013 at 15:52 Comment(2)
Custom filters are also powerful =), you might like it, example: noypi-linux.blogspot.com/2014/07/…Kakaaba
Different solution: https://mcmap.net/q/75294/-angularjs-filter-empty-objectsAlvaroalveolar
S
490

See the example on the filter page. Use an object, and set the color in the color property:

Search by color: <input type="text" ng-model="search.color">
<div ng-repeat="product in products | filter:search"> 
Spall answered 6/2, 2013 at 15:58 Comment(5)
Thanks Mark, are there any benefits to doing it this way rather than the method suggested below?Arsenical
@Seglespaan, not really. You might find that the method presented by bmleite and blesh read nicer, since you can see that you are filtering by color. This method is more compact, which might be useful if you want to search by multiple properties, and you'd rather not have a long object in the HTML: filter:{ color: '...', size: '...', ...}Spall
@MarkRajcok, how would I be able to search by multiple properties, looking at the union, rather than intersection?Appendicectomy
@jetcom, you'll need a custom filter, see https://mcmap.net/q/75295/-how-to-apply-a-filter-on-multiple-objects-using-angularjsSpall
I don't know if the OP was asking how to make a search box as much as how to filter out values in an ng-repeat when they're repeating on page. The answer beneath this one seems most relevant to the question asked.Sodality
R
591

Specify the property (i.e. colour) where you want the filter to be applied:

<div ng-repeat="product in products | filter:{ colour: by_colour }">
Rely answered 6/2, 2013 at 16:1 Comment(9)
what if i want ! by_colour as filter:{ colour: ! by_colour }"Blemish
@Blemish just prepend '!'+, like this <div ng-repeat="product in products | filter:{ colour: '!'+by_colour }">Rely
Not sure if I understood it correctly, but the first thing that came to my mind was: <div ng-repeat="product in products | filter:{ resultsMap.annie: '!!' }"> or (something equivalent) like this: <div ng-repeat="product in products | filter:by"> and on the controller: $scope.by = { 'resultsMap.annie': '!!' };. This second approach gives you more control over the property being filtered. Note: '!!' means "not null".Rely
How could i do this dynamically? for example something like <div ng-repeat="product in products | filter:customFilter"> where customFilter = '{ colour: by_colour }' and then that customFilter would be able to change dynamically.Lvov
@Federico, the customFilter can be a simple object on your scope that you update whenever needed. Check this plunker.Rely
Yeah, found that out a bit after posting. I was trying to do it inline with the html something like <span ng-init="by={ resultsMap.annie: '!!' }" and ng-clicks to change it. But it wouldn't work. I guess it was reading it as a string instead of JSON object. Doing it in the controller worked perfect.Lvov
How can I use this type of filter for 2 or more colors. Like if my array got 10 types of color I need to filter red and green at the same time using a check box.. Is there any way to do so.Epsilon
This should be the accepted answer. It is the most succinct. Well, except that 'colour' has too many vowels.Hyrup
I had to put single quotes around my filter field e.g. <div ng-repeat="product in products | filter:{ 'colour': by_colour }">Laminar
S
490

See the example on the filter page. Use an object, and set the color in the color property:

Search by color: <input type="text" ng-model="search.color">
<div ng-repeat="product in products | filter:search"> 
Spall answered 6/2, 2013 at 15:58 Comment(5)
Thanks Mark, are there any benefits to doing it this way rather than the method suggested below?Arsenical
@Seglespaan, not really. You might find that the method presented by bmleite and blesh read nicer, since you can see that you are filtering by color. This method is more compact, which might be useful if you want to search by multiple properties, and you'd rather not have a long object in the HTML: filter:{ color: '...', size: '...', ...}Spall
@MarkRajcok, how would I be able to search by multiple properties, looking at the union, rather than intersection?Appendicectomy
@jetcom, you'll need a custom filter, see https://mcmap.net/q/75295/-how-to-apply-a-filter-on-multiple-objects-using-angularjsSpall
I don't know if the OP was asking how to make a search box as much as how to filter out values in an ng-repeat when they're repeating on page. The answer beneath this one seems most relevant to the question asked.Sodality
M
177

You can filter by an object with a property matching the objects you have to filter on it:

app.controller('FooCtrl', function($scope) {
   $scope.products = [
       { id: 1, name: 'test', color: 'red' },
       { id: 2, name: 'bob', color: 'blue' }
       /*... etc... */
   ];
});
<div ng-repeat="product in products | filter: { color: 'red' }"> 

This can of course be passed in by variable, as Mark Rajcok suggested.

Mainly answered 6/2, 2013 at 16:0 Comment(3)
lets say that i have this kind of scope.products: { id: 1, name: 'test', color: 'lightblue' }, { id: 2, name: 'bob', color: [{foreground : black, background:white}] }. then how can i filter product based on color:background to get white value?Cudgel
@Gery: Honestly, I don't think you can. Either way, using filter: at all is sort of bad practice, IMO. In that it puts logic in your view that should really be in your controller, and isn't very testable.Mainly
This is a way to move the filtering to the controller and extend the model. ozkary.com/2015/05/angularjs-value-mapping-with-dynamic.html.Tar
B
108

If you want to filter on a grandchild (or deeper) of the given object, you can continue to build out your object hierarchy. For example, if you want to filter on 'thing.properties.title', you can do the following:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter } }">

You can also filter on multiple properties of an object just by adding them to your filter object:

<div ng-repeat="thing in things | filter: { properties: { title: title_filter, id: id_filter } }">
Billie answered 15/10, 2014 at 21:46 Comment(3)
is this like 'or' type or 'and' type of filter.Chronicle
Same question is that an AND or an OR when filtering more than one property?Magocsi
for OR filter only way is custom filter, I thinkFieldsman
P
107

Best way to do this is to use a function:

html

<div ng-repeat="product in products | filter: myFilter">

javascript

$scope.myFilter = function (item) { 
    return item === 'red' || item === 'blue'; 
};

Alternatively, you can use ngHide or ngShow to dynamically show and hide elements based on a certain criteria.

Panettone answered 20/7, 2015 at 6:45 Comment(2)
Thank you, this is very useful when you have complex comparisonsBollworm
Using ng-hide was perfect and exactly what I needed.Gangster
M
66

Be careful with angular filter. If you want select specific value in field, you can't use filter.

Example:

javascript

app.controller('FooCtrl', function($scope) {
   $scope.products = [
       { id: 1, name: 'test', color: 'lightblue' },
       { id: 2, name: 'bob', color: 'blue' }
       /*... etc... */
   ];
});

html

<div ng-repeat="product in products | filter: { color: 'blue' }"> 

This will select both, because use something like substr
That means you want select product where "color" contains string "blue" and not where "color" is "blue".

Moynahan answered 2/5, 2013 at 7:22 Comment(1)
<div ng-repeat="product in products | filter: { color: 'blue' }:true"> will work on only exact matches (the 'true' at the end is the comparator argument: linkSkimmer
W
24

Search by color:

<input type="text" ng-model="searchinput">
<div ng-repeat="product in products | filter:{color:searchinput}">

you can do an inner nest too.

filter:{prop1:{innerprop1:searchinput}}
Witkin answered 1/5, 2017 at 18:19 Comment(0)
G
10

If you were to do the following:

<li class="active-item" ng-repeat="item in mc.pageData.items | filter: { itemTypeId: 2, itemStatus: 1 } | orderBy : 'listIndex'"
                id="{{item.id}}">
    <span class="item-title">{{preference.itemTitle}}</span>
</li>

...you would not only get items of itemTypeId 2 and itemStatus 1, but you would also get items with itemType 20, 22, 202, 123 and itemStatus 10, 11, 101, 123. This is because the filter: {...} syntax works like a string contains query.

However, if you were to add the : true condition, it would do filter by exact match:

<li class="active-item" ng-repeat="item in mc.pageData.items | filter: { itemTypeId: 2, itemStatus: 1 } : true | orderBy : 'listIndex'"
                id="{{item.id}}">
    <span class="item-title">{{preference.itemTitle}}</span>
</li>
Gallivant answered 29/9, 2016 at 9:3 Comment(0)
L
7

my way is this

subjcts is

[{"id":"1","title":"GFATM"},{"id":"2","title":"Court Case"},{"id":"3","title":"Renewal\/Validity"},{"id":"4","title":"Change of Details"},{"id":"5","title":"Student Query"},{"id":"6","title":"Complains"}]

sub is a Input field or whatever you like

Displaying like this

<div ng-if="x.id === sub" ng-repeat=" x in subjcts">{{x.title}}</div>
Lyons answered 11/4, 2016 at 10:46 Comment(1)
In general using ng-if is a clean solutionPhysiotherapy
D
4

You must use filter:{color_name:by_colour} instead of

filter:by_colour

If you want to match with a single property of an object, then write that property instead of object, otherwise some other property will get match.

Ditmore answered 17/3, 2017 at 20:12 Comment(0)
I
1

Specify the property in filter, of object on which you want to apply filter:

//Suppose Object
var users = [{
  "firstname": "XYZ",
  "lastname": "ABC",
  "Address": "HOUSE NO-1, Example Street, Example Town"
},
{
  "firstname": "QWE",
  "lastname": "YUIKJH",
  "Address": "HOUSE NO-11, Example Street1, Example Town1"
}]

But you want to apply filter only on firstname

<input type = "text" ng-model = "first_name_model"/>
<div ng-repeat="user in users| filter:{ firstname: first_name_model}">
Inferno answered 13/2, 2018 at 6:57 Comment(0)
S
0

If you want filter for one field:

label>Any: <input ng-model="search.color"></label> <br>
<tr ng-repeat="friendObj in friends | filter:search:strict">

If you want filter for all field:

 label>Any: <input ng-model="search.$"></label> <br>
 <tr ng-repeat="friendObj in friends | filter:search:strict">

and https://docs.angularjs.org/api/ng/filter/filter good for you

Samoyed answered 20/7, 2018 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.