Search code examples
angularjsangular-ng-if

Update <select> tag inside ng-if in angularjs


I would like to update the list of states on selection of country. I have researched a bit into this where it was recommended to use $parent as ng-if does not work on controller scope.But that too is not working for me.

Can someone please help me understand how to get the values into state select control.

Also I would also like to know what if there are multiple ng-if in my HTML. (again nested $parent.$parent.$parent... is not working)

Plunker Link : Plunker Link

"use strict";

var app = angular.module("app", []);

function CountriesController($scope) {
  $scope.condition = true;
    $scope.countries = [{
        "name": "USA",
        "id": 1
      },{
        "name": "Canada",
        "id": 2
    }];
    
    $scope.states = [{
        "name": "Alabama",
        "id": 1,
        "countryId": 1
      }, {
        "name": "Alaska",
        "id": 2,
        "countryId": 1
      }, {
        "name": "Arizona",
        "id": 3,
        "countryId": 1
      }, {
        "name": "Alberta",
        "id": 4,
        "countryId": 2
      }, {
        "name": "British columbia",
        "id": 5,
        "countryId": 2
    }];
    
    $scope.updateCountry = function(){
      $scope.availableStates = [];
      
      angular.forEach($scope.states, function(value){
        if(value.countryId == $scope.country.id){
          $scope.availableStates.push(value);
        }
      });
    }
}
<!DOCTYPE html>
<html data-ng-app="app">

<head>
  <script data-require="angular.js@1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body data-ng-controller="CountriesController">
  <div ng-if="condition">
    <select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()">
      <option value="">Select country</option>
    </select>
    <br>
    <select data-ng-model="state" data-ng-options="state.name for state in availableStates">
      <option value="">Select state</option>
    </select>
    <br> Country: {{country}}
    <br> State: {{state}}
  </div>
</body>

</html>


Solution

  • Instead of making a separate list, you can use your country list by filtering

     filter: {countryId: $parent.country.id}
    

    "use strict";
    
    var app = angular.module("app", []);
    
    function CountriesController($scope) {
      $scope.condition = true;
        $scope.countries = [{
            "name": "USA",
            "id": 1
          },{
            "name": "Canada",
            "id": 2
        }];
        
        $scope.states = [{
            "name": "Alabama",
            "id": 1,
            "countryId": 1
          }, {
            "name": "Alaska",
            "id": 2,
            "countryId": 1
          }, {
            "name": "Arizona",
            "id": 3,
            "countryId": 1
          }, {
            "name": "Alberta",
            "id": 4,
            "countryId": 2
          }, {
            "name": "British columbia",
            "id": 5,
            "countryId": 2
        }];
        
        $scope.updateCountry = function(){
          $scope.availableStates = [];
          
          angular.forEach($scope.states, function(value){
            if(value.countryId == $scope.country.id){
              $scope.availableStates.push(value);
            }
          });
        }
    }
    <!DOCTYPE html>
    <html data-ng-app="app">
    
    <head>
      <script data-require="angular.js@1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
      <link rel="stylesheet" href="style.css" />
      <script src="script.js"></script>
    </head>
    
    <body data-ng-controller="CountriesController">
      <div ng-if="condition">
        <select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="">
          <option value="">Select country</option>
        </select>
        <br>
        <select data-ng-model="state" data-ng-options="state.name for state in states | filter:{countryId: country.id}:true">
          <option value="">Select state</option>
        </select>
        <br> Country: {{country}}
        <br> State: {{state}}
      </div>
    </body>
    
    </html>