Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chained select within ng-repeat

I'm having trouble figuring out scoping within ng-repeat. I want to create chained selects, and I want to keep each row in the ng-repeat to exist separately in separate scopes. Currently changing the first select in any of the rows will change the second selects in all of the rows.

(Real life example: I have a form where I have to add cars, first choose a 'Make', pull its 'Models' from an api, and show models in the second select. Users must be able to add any number of cars.)

HTML:

<div ng-controller="MyCtrl">
  <div ng-repeat="row in rows">
    <select ng-options="option.value as option.title for option in options1" ng-model="row.select1" ng-change="updateSelect2(row.select1)"></select> 
    <select ng-options="option.value as option.title for option in options2" ng-model="row.select2"></select>
  </div>
  <a ng-click="addRow()">Add Row</a>
</div>

JS:

function MyCtrl($scope) {
  $scope.rows = [{}];
  $scope.options1 = [
    {title: 'Option 1', value: '1'},
    {title: 'Option 2', value: '2'},
    {title: 'Option 3', value: '3'}
  ];

  $scope.options2 = [];

  $scope.updateSelect2 = function(val) {
    if (val === '1') {
      $scope.options2 = [
        {title: 'A', value: 'A'},
        {title: 'B', value: 'B'}
      ];
    } else if (val === '2') {
      $scope.options2 = [
        {title: 'AA', value: 'AA'},
        {title: 'BB', value: 'BB'}
      ];
    } else {
      $scope.options2 = [
        {title: 'AAA', value: 'AAA'},
        {title: 'BBB', value: 'BBB'}
      ];
    }
  };

  $scope.addRow = function() {
    $scope.rows.push({});
  };
}

FIDDLE HERE

like image 881
orszaczky Avatar asked Sep 26 '22 20:09

orszaczky


1 Answers

You need to have the options2 part separated for each row.

A simple solution will be to just save it inside the row object, but you might want a more elaborate data structure.

Here is a simple example using your code.

HTML:

<div ng-repeat="row in rows">
  <select ng-options="option.value as option.title for option in options1" ng-model="row.select1" ng-change="updateSelect2(row.select1, $index)">  </select> 
  <select ng-options="option.value as option.title for option in row.options2" ng-model="row.select2"></select>
</div>

JS:

$scope.updateSelect2 = function(val, index) {
  if (val === '1') {
    $scope.rows[index].options2 = [
      {title: 'A', value: 'A'},
      {title: 'B', value: 'B'}
    ];
  } else if (val === '2') {
    $scope.rows[index].options2 = [
      {title: 'AA', value: 'AA'},
      {title: 'BB', value: 'BB'}
    ];
  } else {
    $scope.rows[index].options2 = [
      {title: 'AAA', value: 'AAA'},
      {title: 'BBB', value: 'BBB'}
    ];
  }
};
like image 179
Yaron Schwimmer Avatar answered Oct 03 '22 23:10

Yaron Schwimmer