Search code examples
javascripthtmlangularjsservicenow

How to populate dynamic options for multiple Selects inside a ng-repeat


I am adding dynamic rows by clicking "add Row" button in an Html form. In a row, I have 'Country' select and 'State' select. Whenever i select country, states are populated properly in first row and in second row onward if i change country all other row values are also changing. Please help. In the below code , "data.states" array, i am loading from database. but the problem is among multiple rows, states array is getting overridden for each country change.

 <table>
       <tr>
         <th>Country</th>
         <th>State</state>
         <th>Action</th>
       </tr>
       <tr ng-repeat="model in models track by $index">
          <td>
               <select ng-options="country in countries" ng-model="country" ng-change='getState(country)'>
               </select>
          </td>
          <td>
              <select ng-options="state in data.states">
              </select>
          </td>
          <td><button ng-click="addRow()">Add Row</button></td>
       </tr>
    </table>

$scope.models = [{}];

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

Solution

  • The issue is that all your code is using the same ng-model reference for the country and also, you're not using different variables on the scope to store your states for each country in here: <select ng-options="state in data.states"></select>

    Try the code bellow

        <table>
           <tr>
             <th>Country</th>
             <th>State</th>
             <th>Action</th>
           </tr>
           <tr ng-repeat="model in models">
              <td>
                   <select ng-options="country as country for country in countries" ng-model="model.country" ng-change='getState(model.country)'>
                   </select>
              </td>
              <td>
                  <select ng-options="state as state for state in getState(model.country)" ng-model="model.state">
                  </select>
              </td>
              <td><button ng-click="addRow()">Add Row</button></td>
           </tr>
        </table>
    
    
      $scope.models = [{}];
    
      $scope.countries = ['Brazil', 'Canada', 'US'];
    
      $scope.states = {
        Brazil: ['Rio de Janeiro', 'Acre', 'Bahia'],
        Canada: ['Ontario', 'Alberta', 'Manitoba'],
        US: ['California', 'Florida', 'Texas'],
      }
    
      $scope.addRow = function(){
        $scope.models.push({});
      }
    
      $scope.getState = function(country){
        // implement your fetch state logic here
        return $scope.states[country];
      }
    

    Here's a working plunker: https://plnkr.co/edit/coh5niQXon10l5RHYKza?p=info