1

I am trying to implement cascading <select> in angular from some json data.

Basically as soon as user selects a director then the movies dropdown is populated with that directors films.

However I am not sure how to access the set of childitems for a director in the json in the ng-repeat for the movies <select>

The selects are as follows. The first dropdown is populated on load with all director's id and name

<select name="directors" id="directors" ng-model="searchFilter.directorId">
    <option ng-repeat="item in directors" value="{{item.id}}">{{item.name}}</option>
</select>
<select name="movies" id="movies" ng-disabled="!searchFilter.movieId" ng-model="searchFilter.movieId">
    <option ng-repeat="item in directors.childItems" value="{{item.id}}">{{item.name}}</option>
</select>

The json is

[{
        "childItems": [{
                "childItems": null,
                "id": 3,
                "name": "Star Wars"
            }
        ],
        "id": 168,
        "name": "George Lucas"
    }, {
        "childItems": [{
                "childItems": null,
                "id": 10,
                "name": "The Hobbit"
            }, {
                "childItems": null,
                "id": 11,
                "name": "The Return of the King"
            }, {
                "childItems": null,
                "id": 30,
                "name": "Fellowship of the Ring"
            }
        ],
        "id": 170,
        "name": "Peter Jackson"
    }, {
        "childItems": [{
                "childItems": null,
                "id": 3,
                "name": "Blade Runner"
            }
        ],
        "id": 167,
        "name": "Ridley Scott"
    }, {
        "childItems": [{
                "childItems": null,
                "id": 3,
                "name": "2001 A Space Odyssey"
            }
        ],
        "id": 279,
        "name": "Stanley Kubrick"
    }, {
        "childItems": [{
                "childItems": null,
                "id": 3,
                "name": "Manhattan"
            }
        ],
        "id": 169,
        "name": "Woody Allen"
    }
]

Can anybody help?

2 Answers 2

1

this is easily accomplished by using ng-options.

<select name="directors" id="directors" ng-model="selectedDirector" 
        ng-options="item.name for item in movieList">

<select name="movies" id="movies" ng-disabled="!selectedDirector" ng-model="selectedMovie" 
        ng-options="item.id as item.name for item in selectedDirector.childItems">

Here we use the selectedDirector as the input object on the secondary dropdown. In the secondary dropdown, we use the alternative form to bind item.id to the ng-model, while using the item.name for the label.

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

app.controller('MainCtrl', function($scope) {


  $scope.movieList = [{
    "childItems": [{
      "childItems": null,
      "id": 3,
      "name": "Star Wars"
    }],
    "id": 168,
    "name": "George Lucas"
  }, {
    "childItems": [{
      "childItems": null,
      "id": 10,
      "name": "The Hobbit"
    }, {
      "childItems": null,
      "id": 11,
      "name": "The Return of the King"
    }, {
      "childItems": null,
      "id": 30,
      "name": "Fellowship of the Ring"
    }],
    "id": 170,
    "name": "Peter Jackson"
  }, {
    "childItems": [{
      "childItems": null,
      "id": 3,
      "name": "Blade Runner"
    }],
    "id": 167,
    "name": "Ridley Scott"
  }, {
    "childItems": [{
      "childItems": null,
      "id": 3,
      "name": "2001 A Space Odyssey"
    }],
    "id": 279,
    "name": "Stanley Kubrick"
  }, {
    "childItems": [{
      "childItems": null,
      "id": 3,
      "name": "Manhattan"
    }],
    "id": 169,
    "name": "Woody Allen"
  }]
});
<script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js" data-semver="1.5.10"></script>

<div ng-app="plunker" ng-controller="MainCtrl">

  <select name="directors" id="directors" ng-model="selectedDirector" ng-options="item.name for item in movieList">
  </select>
  <pre>{{selectedDirector}}</pre>
  <select name="movies" id="movies" ng-disabled="!selectedDirector" ng-model="selectedMovie" ng-options="item.id as item.name for item in selectedDirector.childItems">
  </select>
  <pre>{{selectedMovie}}</pre>

</div>

http://plnkr.co/edit/qQVjhssFlFDXIzLm4LdQ?p=preview

Sign up to request clarification or add additional context in comments.

Comments

0

The simplest thing would be to use whole director object in searchFilter and then reference it when building list of movies

<select name="directors" id="directors" ng-model="searchFilter.director">
    <option ng-repeat="item in directors" ng-value="item">{{item.name}}</option>
</select>
<select name="movies" id="movies" ng-model="searchFilter.movieId">
    <option ng-repeat="item in searchFilter.director.childItems" value="{{item.id}}">{{item.name}}</option>
</select>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.