Search code examples
javascriptangularjsangularjs-ng-options

How to convert id as order number in ng-options group by..?


This is my code

Fiddle Link

HTML

<div ng-app ng-controller="MyCtrl">
   <input type="text" ng-model = "data.name" ><br>
   <input type="text" ng-model = "data.value" ><br>
   <input type="text" ng-model = "data.id" ><br>
   <input type="button" value="ADD" ng-click = "addIntoArr(data.name, 
       data.value, data.id)" ng-disabled= !data.name>
   <select ng-model="selectItem"  ng-options="currOption as 'order' + 
     (data.indexOf(currOption)+1) group by currOption.name for currOption
         in data"></select>
   Data : {{selectItem.name}} 
</div>

Here is my Js code

  function MyCtrl($scope) {
    $scope.data = [{
       name: "AM",
       value: "11",
       id: "2"
    }, {
       name: "PM",
       value: "12",
       id: "3"
    }, {
      name: "PM",
      value: "12",
      id: "23"
    }, {
      name: "PM",
      value: "12",
      id: "33"
    }, {
      name: "AMT",
      value: "13",
      id: "33"
    }, {
      name: "WAT",
      value: "14",
      id: "21"
   }];

  $scope.addIntoArr = function (name, value, id) {
     $scope.data.push({
        name: name,
        value: value,
        id: id
    });
  }
   $scope.selectItem = $scope.data[0];
}

Here is my array I was using label AM, PM, AWT, WAT. and each has a order (Please check fiddle link). I want each label order show with number like order1 in AM, order1, order2, order3 in PM and so on. and if I add new entry in array then recently added entry should be shown in drop down with order number and Related label shown in Data.


Solution

  • I'd suggest you include some external library like lodash and format your data into more convenient structure. Then, instead of banging your head against the wall with ng-options, you could use ng-repeat.

    Consider the following:

    // group existing data by object's name using lodash _.groupBy
    $scope.groupedData = _.groupBy($scope.data, 'name'); 
    

    This gives your following data structure for groupedData, so there's key and value where key is e.g. AM and value is array of objects all having same name.

    imgur

    Then you could have following template for your select.

    <select ng-model="selectItem">
      <optgroup ng-repeat="(key, items) in groupedData" label="{{ key }}">
        <option ng-repeat="item in items" 
                value="{{ item }}" 
                ng-bind="'order' + (items.indexOf(item) + 1)"></option>
      </optgroup>    
    </select>
    

    Which gives you what you are after, no?

    imgur