ng-repeat :filter by single field - angularjs

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?

Specify the property (i.e. colour) where you want the filter to be applied:
<div ng-repeat="product in products | filter:{ colour: by_colour }">

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">

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.

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 } }">

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.

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".

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}}

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>

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>

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.

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}">

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

Related

How to create a unique hyperlink for each element in an angularjs array

So i have an array of random names and i want each name in the array to have its own hyperlink. When displayed it should basically be a list of names that each link to different pages, how do i go about giving each name in the array a different hyperlink? I attached a snippet of the html and js.
$scope.artists=[
{
name: "Noelle",
rank: "Gold",
worth: 752000,
},
{
name: "John",
rank: "Silver",
worth: 700000,
},
{
name: "Shem",
rank: "Green",
worth: 5687952,
},
<ul>
<li ng-repeat="artist in artists | orderBy: order | filter: search">
<h3>{{artist.name}} - {{artist.worth | currency:'£'}}</h3>
<div class="remove" ng-click="removeArtist(artist)">x</div>
<span class="rank" style="background:{{artist.rank}}">{{artist.rank}}</span>
</li>
</ul>
You would include the href as part of the artist object - and have a standard URL that differs only in the name of the artist.
In the following I am interpolating the artist into the href of the a. Note that I am coding this as a link property with the artists full name in case there are two artists with the same first name.
Note that hovering over the link text will show you the link href - if you click it - nothing will show since there isnt a corresponding page to navigate to.
var app = angular.module('myApp', []);
app.controller('myController', function ($scope) {
$scope.artists=[
{
name: "Noelle",
rank: "Gold",
worth: 752000,
link: "noelle-smith"
},
{
name: "John",
rank: "Silver",
worth: 700000,
link: "john-jones"
},
{
name: "Shem",
rank: "Green",
worth: 5687952,
link: "shem-willis"
}]
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
<ul>
<li ng-repeat="artist in artists | orderBy: order | filter: search">
<h3>{{artist.name}} - {{artist.worth | currency:'£'}}</h3>
<span class="rank" style="background:{{artist.rank}}">{{artist.rank}}</span><br/>
View Artist
</li>
</ul>
</div>

use orderBy for value in array

I have nested ng-repeat that extracts data from the server:
<div ng-repeat="x in result | filter:sellbox " >
<div ng-repeat="z in x.data | orderBy:'??' " >
{{x.rate_type}} to {{x.name}} {{z[1]}}
</div>
</div>
This is part of the server:
"result":[
{
"id":"BNLN_USD",
"code":"BNLN",
"name":"National Bank Of Georgia (BNLN)",
"currency":"USD",
"rate_type":"reference",
"color":"#4b4a4b",
"legendIndex":1,
"data":[
[
1473033600000,
2.2938
]
]
},
{
"id":"BAGA_USD_B",
"code":"BAGA",
"name":"Bank Of Georgia (BAGA)",
"currency":"USD",
"rate_type":"buy",
"color":"#ed7623",
"dashStyle":"shortdot",
"legendIndex":2,
"data":[
[
1473033600000,
2.25
]
]
}
z[1] is giving the value of 2.2938 and 2.25 in this segment. How do I use orderBy so that the results are ordered in decreasing order of z[1].
Since AngularJS 1.3.0-rc.5, the orderBy filter will automatically sort the array using its items if no additional parameters are provided.
<div ng-repeat="z in x.data | orderBy">{{item}}</div>
The reason you couldn't orderBy was that your data is an array of array, so you have to call a custom orderBy function.
In your controller
$scope.customOrder = function (content) {
return content.sort()[0];
}
In your HTML pass the customOrder function and pass true to make it descending
<div ng-repeat="x in result | filter:sellbox " >
<div ng-repeat="z in x.data | orderBy:customOrder:true">
{{x.rate_type}} to {{x.name}} {{z[1]}}
</div>
</div>
I managed to solve this by mapping my results:
JS:
$rootScope.bank_data = $rootScope.result.map(function(x){
return {
rate_type: x.rate_type,
name: x.name,
value :x.data[0][1]
};
})
HTML:
<input type="searchbox" ng-model="sellbox" ng-hide="buy" >
<div ng-repeat="m in bank_data | filter:sellbox | orderBy:'-value'" > {{m.rate_type}} {{m.name}} {{m.value}}</div>
This way I managed to display the array I wanted to sort and it worked just fine. Thank you everyone for helping.

Angular using ng-repeat variable in nested ng-repeat

I have an ng-repeat which iterates over an array of values:
var englishList = ["abo", "ser", "vol", "con", "giv", "blo"];
$scope.englishList = englishList;
Is there a way to loop over these values in an ng-repeat and use the returned value as part of a nested ng-repeat?
<div ng-repeat="api in englishList">
<div ng-repeat="result in searchData.abo | filter:searchText">
<li>{{result.title}} {{result.shortname}}</li>
</div>
</div>
Ideally, I'd like this line to interpolate the each ng-repeat value from $scope.englishList:
<div ng-repeat="result in searchData.{{api}} | filter:searchText">
Is there a way to do this in angular?
You should be able to do something like this, surely:
<div ng-repeat='api in englishList'>
<div ng-repeat='item in searchData[api]'>
<!-- uses the value of 'api' as a key in 'searchData' -->
<!-- you do not need to use interpolation here as these are already expressions -->
</div>
</div>
I can't really give a complete example as your code is not exactly obvious in how you would want to use the nested type, but the above snippet should give you an idea of HOW to use nested repeats.
I would advise you use an object model like so
{ "api": {
"foo": [ "bar", "baz", "qux" ]
}}
Rather than having two different arrays. This should make it less brittle. Remember that your view's logic should ideally be as simple as possible and it shouldn't have to do much manipulation on the data given to it to work. I would say that iterating one array and then iterating another using the values of array 1 as keys of array 2 is maybe a bit too much for the view to do.
Just use the bracket notation to dynamically access a property :
<div ng-repeat="api in englishList">
<div ng-repeat="result in searchData[api] | filter: searchText" >
<li>{{result.title}}, {{result.shortname}}</li>
</div>
</div>
Snippet :
angular.module('demoApp', []).controller('DemoController', function ($scope) {
$scope.englishList = ["abo", "ser", "vol", "con"];;
$scope.searchData = {
abo: [{
title: 'title abo',
shortname: 'shortname abo'
}],
ser: [{
title: 'title ser 1',
shortname: 'shortname ser 1'
}, {
title: 'title ser 2',
shortname: 'shortname ser 2'
}],
vol: [{
title: 'title vol',
shortname: 'shortname vol'
}],
con: [{
title: 'title con',
shortname: 'shortname con'
}]
};
});
p {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="DemoController">
<div>Search <input type="text" ng-model="searchText"/></div>
<div ng-repeat="api in englishList">
<p>{{api}}</p>
<div ng-repeat="result in searchData[api] | filter: searchText" >
<li>{{result.title}}, {{result.shortname}}</li>
</div>
</div>
</div>

AngularJS filter for nested objects

I have an array of objects with arrays of objects in it:
var content = [
{
name: 'Foo',
sub: [{ name: 'Bar' }, { name: 'Foobar' }]
},
...
]
and a template:
<input ng-model="search" />
<div ng-repeat="item in content | filter:search>
{{item.name}}
<div ng-repeat="key in item">
{{key.name}}
</div>
</div>
Now, I use the filter filter to search for string matches, but it applies only to the first ng-repeat directive. How could I include the second directive into the search filter? Thanks in advance.
You can simply apply a second filter expression to your other ng-repeat
<div ng-repeat="key in item | filter:secondFilterExpression">
See docs here http://docs.angularjs.org/api/ng.filter:filter
Ok, I've 'flattened' the object to a simple collection before passing it through the controller to the template, so I don't have to worry about a second ng-repeat cycle. The output is
[{ name : 'foo' }, { name : 'bar' }, { name : 'foobar' }]

Assign a value to filters in Angularjs?

My JSON data are like: records.json
[
{
"id":"1",
"name":"Report1",
"category":"A"
},
{
"id":"2",
"name":"Report2",
"category":"A"
},
{
"id":"3",
"name":"Report3",
"category":"B"
},
{
"id":"4",
"name":"Report4",
"category":"C"
}
]
and HTML page is like :
<input ng-model="query" />
<li ng-repeat="record in records | filter:query" />
This code gives the list of records according to query, but i want only those records which having only category A.
As explain by the AngularJS documentation, you can simply do something like that :
<li ng-repeat="record in records | filter: {category:'A', name:query}">
<!-- ... -->
</li>
Notice that if your filter becomes to heavy, it is probably a best idea to make your own filter.

Resources