<!DOCTYPE html>
<html>

  <head>
    <link data-require="bootstrap@*" data-semver="3.2.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css" />
    <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>
    <script data-require="angular.js@*" data-semver="1.4.0-beta.0" src="https://code.angularjs.org/1.4.0-beta.0/angular.js"></script>
    <script data-require="underscore.js@*" data-semver="1.6.0" src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="optionsApp">
    <h1>Angular ng-Options by Example</h1>
    <p>I use ngOptions infrequently enough that I don't remember how the comprehension expression
    works, but often enough that hunting down appropriate examples is a nuisance. So I've compiled
    a set of working examples here. I don't have 'track by' examples because they're for performance
    and/or UI issues around refreshing data sources. Seems like a lot to accomplish here, and they
    should be easy enough to 'tack on' as needed.
    </p>
    <div style="white-space: pre; font-family: monospace">
  $scope.a = ['foo', 'bar', 'baz'];
  $scope.pojo = {
        pb:     {id: 7, type: 'Spread', name: 'Peanut Butter'},
        yellow: {id: 4, type: 'Condiment',  name: 'Mustard'},
        j:      {id: 3, type: 'Spread', name: 'Jelly'},
        jam:    {id: 2, type: 'Spread', name: 'Jam'},
        minty:  {id: 1, type: 'Condiment',  name: 'Mint Jelly'}
      };
  $scope.ao = [
        {id: 7, type: 'Spread', name: 'Peanut Butter'},
        {id: 4, type: 'Condiment',  name: 'Mustard'},
        {id: 3, type: 'Spread', name: 'Jelly'},
        {id: 2, type: 'Spread', name: 'Jam'},
        {id: 1, type: 'Condiment',  name: 'Mint Jelly'}
      ];
  $scope.range = _.range(6, 12);
    </div>
    <table ng-controller="optionsCtrl" class="table table-bordered">
      <tbody>
        <tr>
          <th colspan="4">array data sources</th>
        </tr>
        <tr>
          <th>form</th>
          <th>actual</th>
          <th>result</th>
          <th>value</th>
        </tr>
        <tr>
          <td>label for value in array</td>
          <td>thing for thing in a</td>
          <td>
            <select ng-model="avalue1" ng-options="thing for thing in a"></select>
          </td>
          <td>{{ avalue1 }}</td>
        </tr>
        <tr>
          <td></td>
          <td>option|uppercase for option in a</td>
          <td>
            <select ng-model="ovalue" ng-options="option|uppercase for option in a"></select>
          </td>
          <td>{{ ovalue }}</td>
        </tr>
        <tr>
          <td></td>
          <td>number for number in range</td>
          <td>
            <select ng-model="rangevalue" ng-options="number for number in range"></select>
          </td>
          <td>{{ rangevalue }}</td>
        </tr>
        <tr>
          <td></td>
          <td>option.name for option in ao</td>
          <td>
            <select ng-model="aovalue1" ng-options="option.name for option in ao"></select>
          </td>
          <td>{{ aovalue1 }}</td>
        </tr>
        <tr>
          <td>select as label for value in array</td>
          <td>option.id as option.name for option in ao</td>
          <td>
            <select ng-model="aovalue2" ng-options="option.id as option.name for option in ao"></select>
          </td>
          <td>{{ aovalue2 }}</td>
        </tr>
        <tr>
          <td>label group by group for value in array</td>
          <td>option.name group by option.type for option in ao</td>
          <td>
            <select ng-model="aovalue3" ng-options="option.name group by option.type for option in ao"></select>
          </td>
          <td>{{ aovalue3 }}</td>
        </tr>
        <tr>
          <td>select as label group by group for value in array</td>
          <td>option.id as option.name group by option.type for option in ao</td>
          <td>
            <select ng-model="aovalue4" ng-options="option.id as option.name group by option.type for option in ao"></select>
          </td>
          <td>{{ aovalue4 }}</td>
        </tr>
        <tr>
          <th colspan="4">object data sources</th>
        </tr>
        <tr>
          <td>label for value in object</td>
          <td>item.name for item in pojo</td>
          <td>
            <select ng-model="o1" ng-options="item.name for item in pojo"></select>
          </td>
          <td>{{ o1 }}</td>
        </tr>
        <tr>
          <td>label for (key , value) in object</td>
          <td>key for (key, item) in pojo</td>
          <td>
            <select ng-model="o2" ng-options="key for (key, item) in pojo"></select>
          </td>
          <td>{{ o2 }}</td>
        </tr>
        <tr>
          <td>select as label for (key , value) in object</td>
          <td>key as spread.name for (key, spread) in pojo</td>
          <td>
            <select ng-model="o3" ng-options="key as spread.name for (key, spread) in pojo"></select>
          </td>
          <td>{{ o3 }}</td>
        </tr>
        <tr>
          <td>label group by group for (key, value) in object</td>
          <td>id group by item.type for (id, item) in pojo</td>
          <td>
            <select ng-model="o4" ng-options="id group by item.type for (id, item) in pojo"></select>
          </td>
          <td>{{ o4 }}</td>
        </tr>
        <tr>
          <td>select as label group by group for (key, value) in object</td>
          <td>code as item.name group by item.type for (code, item) in pojo</td>
          <td>
            <select ng-model="o5" ng-options="code as item.name group by item.type for (code, item) in pojo"></select>
          </td>
          <td>{{ o5 }}</td>
        </tr>
      </tbody>
    </table>
  </body>

</html>
angular.module('optionsApp', [])
.controller('optionsCtrl', function ($scope) {
  $scope.a = ['foo', 'bar', 'baz'];
  $scope.pojo = {
        pb:     {id: 7, type: 'Spread', name: 'Peanut Butter'},
        yellow: {id: 4, type: 'Condiment',  name: 'Mustard'},
        j:      {id: 3, type: 'Spread', name: 'Jelly'},
        jam:    {id: 2, type: 'Spread', name: 'Jam'},
        minty:  {id: 1, type: 'Condiment',  name: 'Mint Jelly'}
      };
  $scope.ao = [
        {id: 7, type: 'Spread', name: 'Peanut Butter'},
        {id: 4, type: 'Condiment',  name: 'Mustard'},
        {id: 3, type: 'Spread', name: 'Jelly'},
        {id: 2, type: 'Spread', name: 'Jam'},
        {id: 1, type: 'Condiment',  name: 'Mint Jelly'}
      ];
  $scope.range = _.range(6, 12);
  
  
  $scope.pojo = {
    spread: {
      label: 'Spread',
      values: [
        {id: 7, name: 'Peanut Butter'},
        {id: 3, name: 'Jelly'},
        {id: 2, name: 'Jam'}
      ]
    },
    condiment: {
      label: 'Condiment',
      values: [
        {id: 4, name: 'Mustard'},
        {id: 1, name: 'Mint Jelly'}
      ]
    }
  };
});

/* Styles go here */

# Angular ng-Options by Example

I use ngOptions infrequently enough that I don't remember how the comprehension expression
works, but often enough that hunting down appropriate examples is a nuisance. So I've compiled
a set of working examples here. I don't have 'track by' examples because they're for performance
and/or UI issues around refreshing data sources. Seems like a lot to accomplish here, and they
should be easy enough to 'tack on' as needed.