How to bind <select> ng-model using ng-options inside a ng-repeat

I have a list of tasks:

[{
    Titel: "Title1",
    Position: "9"
},{
    Titel: "Title2",
    Position: "1"
},{
    Titel: "Title3",
    Position: "5"
},{
    Titel: "Title4",
    Position: "7"
}]

I'm trying to create a list of <select>, where each is list.lenght long and has a selected value. The html snippet:

<table cellpadding="0" cellspacing="0" border="0">  
    <tr>
        <td class="ms-authoringcontrols"><b>Title</b></td>
        <td class="ms-authoringcontrols"><b>Position</b></td>
    </tr>
    <tr ng-repeat="t in tasks">
        <td>
            <a href="TODO">{{t.Titel}}</a>
        </td>
        <td>
            <select ng-model="t.Position" ng-options="t.Position as tasks.indexOf(i)+1 for i in tasks"></select>
        </td>
    </tr>
</table

Output: enter image description here

What it is missing, is the selected value (position) of each <select>. I Know the value is set by defining the ng-model and ng-model="t.Position" is wrong, but how can I set the Position value of each item to its related select element? The <option>'s of each select should be the length of the tasks and ordered from 1 to n.

Answers:

Answer

You are very close, the ngOptions format you are looking for is select as label for value in array, where select is the value that will be assigned to the model.

In your case Position is string, so we need to convert select to string too so it matches the model:

ng-options="(tasks.indexOf(i)+1).toString() as tasks.indexOf(i)+1 for i in tasks"
            ^ model value                      ^ display

( tasks.indexOf(i)+1+'' would work too)

angular
  .module('Test', [])
  .controller('TestCtrl', function($scope) {
    $scope.tasks = [{
          Titel: "Title1",
          Position: "9"
      },{
          Titel: "Title2",
          Position: "1"
      },{
          Titel: "Title3",
          Position: "3"
      },{
          Titel: "Title4",
          Position: "2"
      }];
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test" ng-controller="TestCtrl">
  <table cellpadding="0" cellspacing="0" border="0">  
      <tr>
          <td class="ms-authoringcontrols"><b>Title</b></td>
          <td class="ms-authoringcontrols"><b>Position</b></td>
      </tr>

      <tr ng-repeat="t in tasks">
          <td>
              <a href="TODO">{{t.Titel}}</a>
          </td>
          <td>
              <select ng-model="t.Position" ng-options="(tasks.indexOf(i)+1).toString() as tasks.indexOf(i)+1 for i in tasks"></select>
          </td>
      </tr>
  </table>
  <pre>{{tasks|json}}</pre>
</div>

(If you run the snippet you will notice the first is not selected, that's because [1,2,3,4] doesn't contain 9.)

Answer

If you want to change the order of the item you need to keep track of the positions in a seperate array.

Here's an working example

angular.module("app", []).controller("myCtrl", function($scope){
$scope.tasks =  [{
    Titel: "Title1",
    Position: "9"
},{
    Titel: "Title2",
    Position: "1"
},{
    Titel: "Title3",
    Position: "5"
},{
    Titel: "Title4",
    Position: "7"
}];
$scope.positions = ["1","2","3","4","5","6","7","8","9"];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="myCtrl">
  <table cellpadding="0" cellspacing="0" border="0">  
    <tr>
        <td class="ms-authoringcontrols"><b>Title</b></td>
        <td class="ms-authoringcontrols"><b>Position</b></td>
    </tr>
    <tr ng-repeat="t in tasks | orderBy: 'Position'">
        <td>
            <a href="TODO">{{t.Titel}}</a>
        </td>
        <td>
            <select ng-model="t.Position" ng-options="i for i in positions"></select>
        </td>
    </tr>
</table>
</div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.