Reputation: 31
I am trying to convert an old PHP/JS project over to straight AngularJS.
The issue I'm running into is that the orderBy:"name"
on my select box is only sort of working.
For example, in the plunker (below) if you open the building drop down, it appears to be in the correct alphabetical order. However, there's a few that are just randomly misplaced throughout the drop down.
The other odd thing is that the JSON file is already in alphabetical order, so I'm not sure what the deal is.
I am new to AngularJS, so I know I'm missing something that's small. Any help would be greatly appreciated. Thanks!
Plunker: http://plnkr.co/edit/wHSERdfKLaYaaSMBph73
JSON Example:
{
"id": 110,
"name": "Administration Center",
"address": null,
"latitude": "41.256326",
"longitude": "-95.973784",
"content": "",
"overlay": "g|xzFnywhQ?^^??j@M??^r@??_@K??kA",
"url": "",
"type_id": 3,
"show_marker": 0,
"show_label": 1,
"custom_marker": "",
"created_at": "2013-07-10 15:40:09",
"updated_at": "2013-07-10 15:42:50",
"color": "#08c"
}
Upvotes: 1
Views: 957
Reputation: 6018
Your plunker had some errors in the order of your dependancies (ie: jquery after angular, etc. There is an error message in the dev console). When using angular and jquery, you have to include jquery first.
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.3/angular.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//cdn.jsdelivr.net/underscorejs/1.5.1/underscore-min.js"></script>
Here is your demo with the fixes: http://plnkr.co/edit/92zvkjP1cx1wBlGqwB4D?p=preview
You do not need to order your data in the controller if you are using the orderBy
filter.
html
<div ng-repeat="(key,menu) in menus">
<h1>{{typeIds[key]}}</h1>
<select ng-model="selectedlocation"
ng-options="item.id as item.name for item in menu | orderBy:'name'">
</select>
</div>
js
function menuController($scope, $http) {
// probably not the best way to do this
$scope.typeIds = {3: "Buildings", 6: "Parking (Fac/Staff)", 7: "Parking (Public)", 8: "Parking (Student)", 11: "Landmarks"};
$http.get('locations.json').then(function(res) {
$scope.locations = res.data;
$scope.menus = _($scope.locations).groupBy('type_id');
/*
// This is not needed anymore
//Convert to array so it sorts correctly on the view side.
$scope.orderedMenus = [];
_($scope.menus).each(function(data, key) {
$scope.orderedMenus.push({"key" : key, "data" : data})
});
*/
});
}
Upvotes: 1
Reputation: 24676
Looks like there's a better solution posted here now. But, just so you know your options in these situations, you can write you own sort as orderBy
can take a sort function, for example:
<select ng-model="selectedlocation" ng-options="value.id as value.name for (key,value) in menu.data | orderBy:sortFunction"></select>
If you add something like the following in your controller:
$scope.sortFunction = function(item){
console.log("Parameter: ", item.name);
}
You'll see you get the item name. If you go this route, your job is to return a value from sortFunction()
that when evaluated against the <, =, > operator produces whatever sort you'd like.
I'm not recommending this route- just mentioning it for completeness sake.
http://docs.angularjs.org/api/ng.filter:orderBy
Upvotes: 0
Reputation: 46599
http://plnkr.co/edit/yRR34nwCBIh6cAiTXIBP?p=preview
It looks to me like ng-select
just doesn't like to order on anything but the value (edit: it looks like that's not right exactly). So I did a bit of sorting in the controller with underscore and made a more explicit select:
<div ng-repeat="menu in orderedMenus | orderBy:'name'"><!-- orderBy might not be necessary here -->
<h1>{{typeIds[menu.key]}}</h1>
<select ng-model="selectedlocation">
<option ng-repeat="item in menu" value="item.id">
{{item.name}}
</option>
</select>
</div>
Which does the trick. Screenshot here.
Upvotes: 0