I have created a Angular Select box for countries. My array looks like this:
AD: "Andorra"
AE: "United Arab Emirates"
AF: "Afghanistan"
AG: "Antigua and Barbuda"
AI: "Anguilla"
And my NgRepeater looks like this
<li nya-bs-option="(k, v) in fields.country.available" data-value="v" data-label="{{v}}">
As you can see, The 'Key' is automatically getting alphabetically arrange in order. However I wish for the 'Value' to be arranged in alphabetical order. I have tried:
<li nya-bs-option="(k, v) in fields.country.available | orderBy:'v'" data-value="v" data-label="{{v}}">
But this didn't work. Can anyone help?
Your array seems more like an object as far as I can see from <key>:<value> structure. In this case you would need to write an own filter for orderBy because angular cannot sort object keys with this filter.
See also: Order by Object key in ng-repeat
Despite of the solution in the thread above, I would suggest to use another structure for the countries if possible:
[{id: 'AD', name: 'Andorra'}, ...]
Then you can do this in ng-repeat:
country in fields.country.available | orderBy: 'id'
I have solved it. And by doing this way, the countries are automatically put into alphabetical order :)
HTML:
<ol class="nya-bs-select" ng-model="data.ship.country" name="ship_{{fields.country.slug}}">
<li nya-bs-option="v in sortable" data-value="v[0]">
<a>{{v[1]}}</a>
</li>
</ol>
Controller:
var countries = fields.country.available,
sortable = [];
for (var country in countries){
sortable.push([country, countries[country]]);
}
sortable.sort(function(a, b) {
return a[1] - b[1]
});
$scope.sortable = sortable;
Related
I am trying to filter an array (list) of repeated objects, based on the value of one of the property. However I keep getting [filter: not array] error. Screenshot of the error:
angular error message
I have also tried adding this angular toArrayFIlter injector https://github.com/petebacondarwin/angular-toArrayFilter however, the error still pops out.
Any help is much appreciated!
My array:
var orders = [
{
"assignedBy": "system",
"serviceDate":"2017-11-13",
"serviceStartTime":"04:00 PM"
},
{
"assignedBy": "system",
"serviceDate":"2017-11-13",
"serviceStartTime":"07:00 AM"
}];
html
<ul ng-repeat="task in orders track by $index | filter: { serviceStartTime: '04:00 PM' }">
<li >
<p>{{task.serviceDate}}</p>
<p>{{task.serviceStartTime}}</p>
</li>
</ul>
You'll need to filter the array before iterating it, like this:
<ul ng-repeat="task in (orders | filter: { serviceStartTime: '04:00 PM' }) track by $index ">
In this JSFiddle (https://jsfiddle.net/eug0taf9/9/), I select a rating and expect an image to be displayed.
What is happening?
When I select rating 'High', 2 images show up instead of 1 because the filter is catching category 'High' and also description 'High' of an image in category 'Low'.
What do I expect to happen?
On selecting rating "High", I only want the category to be filtered. I don't need it to be filtered by description too.
Any suggestions on how to solve this?
HTML code:
<div ng-app="myApp" ng-controller="myCtrl">
<span>Select a rating</span>
<select ng-model="catselect"
ng-options="category for category in imageCategories"
ng-change="valueSelected(catselect)">
<option value>All</option>
</select>
<!--<p>Select <input ng-model="categories"/></p>-->
<ul class="photosmenu">
<li ng-repeat="image in images | filter : catselect" ng-click="setCurrentImage(image)">
<img ng-src="{{image.image}}" alt="{{image.stars}}" width="300px"/>
</li>
</ul><!-- End of List -->
</div>
Angular Code:
var mod = angular.module("myApp", []);
mod.controller("myCtrl", function($scope){
$scope.images = [
{category: 'High', image: 'img/1.png', description: 'Random Photo', stars: '4/5'},
{category: 'Medium', image: 'img/6.png', description: 'ApplePhoto', stars: '3/5'},
{category: 'Low', image: 'img/13.png', description: 'High Top Photo', stars: '2/5'},
{category: 'None', image: 'img/16.png', description: 'Kilt Photo', stars: '0/5'}];
$scope.currentImage = $scope.images[0];
$scope.imageCategories = ["High", "Medium", "Low", "None"];
$scope.valueSelected = function (value) {
if (value === null) {
$scope.catselect = undefined;
}
};
});
That is because you have a global match filter which will match on all properties, if you want to filter on specific property set your filter object accordingly. i.e
<li ng-repeat="image in images | filter :{category: catselect}"
Demo
or you could also set your ng-model to an object,
<select ng-model="catselect.category"
and do:
<li ng-repeat="image in images | filter :catselect"
Demo
Check out documentation:
string: The string is used for matching against the contents of the array. All strings or objects with string properties in array that match this string will be returned. This also applies to nested object properties. The predicate can be negated by prefixing the string with !.
Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1". A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object or its nested object properties. That's equivalent to the simple substring match with a string as described above. The predicate can be negated by prefixing the string with !. For example {name: "!M"} predicate will return an array of items which have property name not containing "M".
just started Angularjs, I have a simple application where orderBy is not working. What is wrong here?
<body ng-init="names=['Ruby','Java','Oracle','Basic']">
<input type="text" data-ng-model="name"/>
<ul>
<li ng-repeat="name in names | orderBy:'name' | filter:name">{{name | uppercase}}</li>
</ul>
<script type="text/javascript" src="js/angular.js"></script>
</body>
The orderBy filter will order an array of objects by a property within each member of the array. So if you say orderBy: 'name' then each member of the array should have a property called name in it. In your array there are no properties of name because your array contains Strings not Objects. If your array looked like:
names = [ { name: 'Ruby' }, { name: 'Java' }, { name: 'Oracle' }, { name: 'Basic'} ]
Then it'd work. Or you can change orderBy: 'name' to orderBy like so:
<li ng-repeat="name in names | orderBy | filter:name">{{name | uppercase}}</li>
Then it won't use a property of the member to order by and instead use the value of each member to order the array which is what you want with Strings.
The orderBy only works with arrays of objects -- See http://docs.angularjs.org/api/ng.filter:orderBy
I made a JSfiddle for you
http://jsfiddle.net/aBccw/
$scope.names =[{name:'Ruby'}, {name:'test'},{name:'Oracle'},{name:'Basic'}];
Hope it helps
Answering my own question. Removed single quote from name and it started working. But not sure if I should stop using quotes?
<li ng-repeat="name in names | orderBy:name | filter:name">{{name | uppercase}}</li>
I have the following fictional object which I'm trying to filter:
{
"0":{
"boy":{
"age":"32",
"name":"Daniel Grey"
}
},
"1":{
"boy":{
"age":"23",
"name":"John Doe"
}
}
}
And then, the ng-repeat directive looks like this:
<ul>
<li ng-repeat="person in people">{{person.boy.name}}<li>
</ul>
My question is, how do I filter people by "name"? I've tried:
<input type="text" ng-model="name">
<ul>
<li ng-repeat="person in people | filter:name">{{person.boy.name}}<li>
</ul>
... but nothing happens [ ng-model seems disconnected from the view! ].
Any response is much appreciated!
Thank you!
Updated answer as per OP's updates
Looking at your fiddle, your $scope.people is essentially an array with one big JSON object, with multiple nested boy objects. This is hard to work with. If you have control over the construction of the JSON object, I will suggest converting into an array of multiple JSON objects, which may look something like:
$scope.people = [
{
"name":"Daniel Grey",
"age":"32",
"gender": "male"
},
{
"name":"John Doe",
"age":"23",
"gender": "male"
}
];
Notice how I converted the boy key into the gender attribute.
If you really have absolutely no control over the data structure, you may have to come up with a custom filter to parse through the nested structure.
Take a look at this fiddle. A few things to pay attention to:
I have to specify people[0] in ng-repeat to retrieve the one big JSON object in your array.
The custom nameFilter searches the .boy.name attribute only.
Original Answer
If you want your filter by just name, you will have to specify the specific attributes in your ng-model directive. So in your case, it will be
<input type="text" ng-model="search.boy.name">
<ul>
<li ng-repeat="person in people | filter:search">{{person.boy.name}}<li>
</ul>
But first you will need to fix your JSON object.
UPDATE:
Live demo on fiddle. I did notice that the search-by-name-only filter doesn't work with angularjs 1.2.1, but works with angularjs 1.2.2.
I am new to angular js so please forgive me for this basic question.
I have an array of object literals and I want to add filter in angular js according to particular field type.
Array of object literals:
var todos= [{text: 'To-DO1', done: false,group:'Group1' }, {text: 'To-do2', done: false, group:'Group2' } ];
I am using this code:
<select data-ng-model="selectOption" data-ng-options="item as item.gtype for item in items"> </select>
<li data-ng-repeat="todo in todos track by $index | filter: selectOption.gtype ">
Above filter is not working
For populating the select I am using :
$scope.items = [
{gtype:'Group1'},
{gtype:'Group2'},`enter code here`
{gtype:'Group3'},
{gtype:'Group4'},
{gtype:'Group5'}
];
Could someone please help me through ?
The problem is with the track by $index. The correct place for it is at the end of the expression, after the filter (see ngRepeat documentation)...
<li data-ng-repeat="todo in todos | filter: selectOption.gtype track by $index">
Live Demo
Edit: As requested, here's an updated fiddle to show an alternate message if filter produces nothing...
Live Demo