Dev
Dev

Reputation: 1746

two level ng-options nested object

EDIT: Using only ng-options as much as possible.

How the data looks like:

vm.category = [
    0: {
        label: 'Label A',
        children: [
            {
                label: 'Label A.1',
                value: 'labelA1',
            }
        ]
    }

    1: {},
    2: {}
]

How it will look like in the HTML. Expected HTML

<select>
    <optionGroup> Label A </optionGroup>
        <option value="labelA1"> Label A.1 </option>
        <option value="labelA2"> Label A.2 </option>
    <optionGroup> Label B </optionGroup>
        <option  value="labelB1"> Label B.1 </option>
</select>

How to achieve this without changing the data structure as much as possible?

I tried ng-options="category.children.label group by category.label for category in vm.categoryTree". But the output is

<select>
    <optionGroup> Label A </optionGroup>
        <option> undefined  </option>
    <optionGroup> Label B </optionGroup>
        <option> undefined </option>
</select>

Upvotes: 1

Views: 1348

Answers (2)

Phil
Phil

Reputation: 164798

Easiest way would be to map the data to a format more easily used by the ng-options "group by" expression

angular.module('so', []).controller('snippet', function() {
  this.categoru = [{"label":"Label A","children":[{"label":"Label A.1","value":"labelA1"}]},{"label":"Label B","children":[{"label":"Label B.1","value":"labelB1"}]}];

  this.options = this.categoru.reduce((flat, group) => {
    Array.prototype.push.apply(flat, group.children.map(child => {
      return Object.assign({
        parent: group.label
      }, child);
    }));
    return flat;
  }, []);
  console.log(this.options);
});
<form ng-app="so" ng-controller="snippet as vm">
  <select ng-model="vm.selected" 
          ng-options="opt.label group by opt.parent for opt in vm.options track by opt.value">
  </select>
  <pre>vm.selected = {{vm.selected | json }}</pre>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>

Upvotes: 3

Sajeetharan
Sajeetharan

Reputation: 222582

You can do this,

 <select ng-model='theModel' ng-change="display(theModel)">
        <optgroup ng-repeat='group in collection' label="{{group.Name}}">
        <option ng-repeat='veh in group.Fields' value='{{group.Name}}::{{veh.Name}}'>{{veh.Name}}</option>
        </optgroup>
</select>

DEMO

Upvotes: 2

Related Questions