# angular.directive.ng:options

Work in Progress This page is currently being revised. It might be incomplete or contain inaccuracies.

## Description

Dynamically generate a list of `<option>` elements for a `<select>` element using an array or an object obtained by evaluating the `ng:options` expression.

When an item in the select menu is select, the value of array element or object property represented by the selected option will be bound to the model identified by the `name` attribute of the parent select element.

Optionally, a single hard-coded `<option>` element, with the value set to an empty string, can be nested into the `<select>` element. This element will then represent `null` or "not selected" option. See example below for demonstration.

Note: `ng:options` provides iterator facility for `<option>` element which must be used instead of `ng:repeat`. `ng:repeat` is not suitable for use with `<option>` element because of the following reasons:

- value attribute of the option element that we need to bind to requires a string, but the source of data for the iteration might be in a form of array containing objects instead of strings
- `ng:repeat` unrolls after the select binds causing incorect rendering on most browsers.
- binding to a value not in list confuses most browsers.

## Usage

    <select ng:options="comprehension">
       ...
    </select>

### Parameters

- `comprehension – {comprehension_expression} –`

  in one of the following forms:

  - for array data sources:
    - `label` `for` `value` `in` `array`
    - `select` `as` `label` `for` `value` `in` `array`
    - `label` `group by` `group` `for` `value` `in` `array`
    - `select` `as` `label` `group by` `group` `for` `value` `in` `array`
  - for object data sources:
    - `label` `for (``key` `,` `value``) in` `object`
    - `select` `as` `label` `for (``key` `,` `value``) in` `object`
    - `label` `group by` `group` `for (``key``,` `value``) in` `object`
    - `select` `as` `label` `group by` `group` `for` `(``key``,` `value``) in` `object`

  Where:

  - `array` / `object`: an expression which evaluates to an array / object to iterate over.
  - `value`: local variable which will refer to each item in the `array` or each property value of `object` during iteration.
  - `key`: local variable which will refer to a property name in `object` during iteration.
  - `label`: The result of this expression will be the label for `<option>` element. The `expression` will most likely refer to the `value` variable (e.g. `value.propertyName`).
  - `select`: The result of this expression will be bound to the model of the parent `<select>` element. If not specified, `select` expression will default to `value`.
  - `group`: The result of this expression will be used to group options using the `<optgroup>` DOM element.

## Example

      <script>
      function MyCntrl(){
        this.colors = [
          {name:'black', shade:'dark'},
          {name:'white', shade:'light'},
          {name:'red', shade:'dark'},
          {name:'blue', shade:'dark'},
          {name:'yellow', shade:'light'}
        ];
        this.color = this.colors[2]; // red
      }
      </script>
      <div ng:controller="MyCntrl">
        <ul>
          <li ng:repeat="color in colors">
            Name: <input name="color.name">
            [<a href ng:click="colors.$remove(color)">X</a>]
          </li>
          <li>
            [<a href ng:click="colors.push({})">add</a>]
          </li>
        </ul>
        <hr/>
        Color (null not allowed):
        <select name="color" ng:options="c.name for c in colors"></select><br>

        Color (null allowed):
        <div  class="nullable">
          <select name="color" ng:options="c.name for c in colors">
            <option value="">-- chose color --</option>
          </select>
        </div><br/>

        Color grouped by shade:
        <select name="color" ng:options="c.name group by c.shade for c in colors">
        </select><br/>

        Select <a href ng:click="color={name:'not in list'}">bogus</a>.<br>
        <hr/>
        Currently selected: {{ {selected_color:color}  }}
        <div style="border:solid 1px black; height:20px"
             ng:style="{'background-color':color.name}">
        </div>
      </div>

       it('should check ng:options', function(){
         expect(binding('color')).toMatch('red');
         select('color').option('0');
         expect(binding('color')).toMatch('black');
         using('.nullable').select('color').option('');
         expect(binding('color')).toMatch('null');
       });