var app = angular.module('plunker', []);
app.filter('orderObjectBy', function(){
return function(input, attribute) {
if (!angular.isObject(input)) return input;
var array = [];
for(var objectKey in input) {
array.push(input[objectKey]);
}
array.sort(function(a, b){
a = parseInt(a[attribute]);
b = parseInt(b[attribute]);
return a - b;
});
return array;
}
});
app.controller('MainCtrl', function($scope) {
$scope.animals =
[
{name: 'Giraffe', phylum: 'Chordata', class: 'Mammalia', order: 'Artiodactyla', family: 'Giraffidae'},
{name: 'Penguin', phylum: 'Chordata', class: 'Aves', order: 'Sphenisciformes', family: 'spheniscidae'},
{name: 'Horse', phylum: 'Chordata', class: 'Mammalia', order: 'Perissodactyla', family: 'Equidae'},
{name: 'Butterfly', phylum: 'Arthropoda', class: 'Insecta', order: 'Lepidoptera' },
{name: 'Bald Eagle', phylum: 'Chordata', class: 'Aves', order: 'Accipitriformes', family: 'Accipitridae'},
{name: 'Starfish', phylum: 'Echinodermata', class: 'Asteroidea'}
]
$scope.hondas =
{
ZEST: {name: 'ZEST', first_year: '2006', pic: 'http://en.wikipedia.org/wiki/File:2007_Honda_Zest_Sports_01.JPG'},
Accord: {name: 'Accord', first_year: '1976', pic: 'http://en.wikipedia.org/wiki/File:%2713_Honda_Accord_Sedan.JPG'},
Jazz: {name: 'Jazz', first_year: '1982', pic: 'http://upload.wikimedia.org/wikipedia/commons/1/1a/Honda_Jazz_1.4_Comfort_Sport-Paket_Ceruleanblue.JPG' },
Odyssey: {name: 'Odyssey', first_year: '1995', pic: 'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e3/2011_Honda_Odyssey_Touring_Elite_--_10-06-2010.jpg/280px-2011_Honda_Odyssey_Touring_Elite_--_10-06-2010.jpg'},
Airwave: {name: 'Airwave', first_year: '2005', pic: 'http://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Honda_Airwave.jpg/280px-Honda_Airwave.jpg'}
}
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<title>AngularJS Plunker</title>
<!-- angular -->
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<!-- your app.js file -->
<script src="app.js"></script>
<!-- bootstrap css -->
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" />
<!-- your style.css file -->
<link href="style.css" rel="stylesheet" />
</head>
<body ng-controller="MainCtrl">
<div class="hero-unit">
<h1>Sort By Property</h1>
<h3>Simple AngularJS Examples / Experiments</h3>
</div>
<div class="well">
<h3>An Array of Animals</h3>
<pre><li ng-repeat="animal in animals"><span>{{</span>animal.name<span>}}</span></li></pre>
<p>produces:</p>
<ul>
<li ng-repeat="animal in animals">{{animal.name}}</li>
</ul>
<p>and I want to sort it by name.</p>
<pre><li ng-repeat="animal in animals|sortBy:'name'"><span>{{</span>animal.name<span>}}</span></li></pre>
<ul>
<li ng-repeat="animal in animals | orderBy:'name'">{{animal.name}}</li>
</ul>
</div>
<div class="alert alert-info">
<p>
<span class="label label-info">Syntax Confusion</span>
You probably want to put quotes around the parameter to sortBy.
</p>
<pre style="background-color: #dff0d8"><li ng-repeat="animal in animals | orderBy:<code>'</code>name<b>'</b>"></pre>
<p>not</p>
<pre style="background-color: #f2dede"><li ng-repeat="animal in animals | orderBy: name "></pre>
<p>
<b>Why?</b>
Angular evaluates the parameter rather than assuming it's a string. This allows you to change your sort method dynamically. See last example for details.
</p>
</div>
<div class="well">
<h3>A Hash of Hondas</h3>
<p>According to <a href="http://stackoverflow.com/questions/14478106/angularjs-sorting-by-property">a Stack Overflow post</a>, you will need to write a custom sorting function if you have a dictionary aka hash of items, rather than an array of them.</p>
<p>My list of Hondas:</p>
<ul>
<li ng-repeat="(name, vehicle) in hondas">{{name}} ( {{vehicle.first_year}} ) </li>
</ul>
<p>can be sorted by the SO filter, using attribute first_year:</p>
<ul>
<li ng-repeat="vehicle in hondas | orderObjectBy:'first_year'">{{vehicle.name}} ( {{vehicle.first_year}} ) </li>
</ul>
<p>As for why the first list is in alphabetical order... I don't know.</p>
</div>
<p class="alert alert-info">
<b>Heads Up!</b>
The sorting function provided here DOES NOT sort by the key! I can only sort by a property name. And it returns just the value of the hash, not the name AND value. So if you had a key that wasn't in the object and you wanted to sort by that, it might be best to just write a loop that added the name to the object. Or you should write a different sorting function.
</p>
</div>
<div class="well">
<h3>Sorting Dynamically</h3>
<p>You can change the way the list is sorted on the fly. This dropdown changes the value <code>$scope.animal_sort_field</code></p>
<select ng-model="animal_sort_field">
<option value="name">Name</option>
<option value="phylum">Phylum</option>
<option value="class">Class</option>
<option value="order">Order</option>
<option value="family">Family</option>
</select>
<p>The sortBy filter gets animal_sort_field as a parameter... <b>sans quotes</b>. My code actually includes a bit of extra code to show you the value on which its being sorted, but this would work just as well:</p>
<pre><li ng-repeat="animal in animals|sortBy:animal_sort_field"><span>{{</span>animal.name<span>}}</span></li></pre>
<ul>
<li ng-repeat="animal in animals | orderBy:animal_sort_field">{{animal.name}}
<span ng-show="animal_sort_field && animal_sort_field != '' && animal_sort_field != 'name'">( {{animal[animal_sort_field]}} )</span></li>
</ul>
</div>
</body>
</html>
/* Put your css in here */