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>&lt;li ng-repeat="animal in animals"&gt;<span>&#123;&#123;</span>animal.name<span>}}</span>&lt;/li&gt;</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>&lt;li ng-repeat="animal in animals|sortBy:'name'"&gt;<span>&#123;&#123;</span>animal.name<span>}}</span>&lt;/li&gt;</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">&lt;li ng-repeat="animal in animals | orderBy:<code>'</code>name<b>'</b>"&gt;</pre>
      <p>not</p>
      <pre style="background-color: #f2dede">&lt;li ng-repeat="animal in animals | orderBy: name "&gt;</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>&lt;li ng-repeat="animal in animals|sortBy:animal_sort_field"&gt;<span>&#123;&#123;</span>animal.name<span>}}</span>&lt;/li&gt;</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 */