angularjs: cascade dropdown

I'm trying to achieve a cascade dropdown in Angular. I thought it would just work naturally thanks to binding. See below:

<select name="client" ng-model="selectedRequest.client" ng-options="c.name for c in clients track by c.id" required></select>
<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in selectedRequest.client.departments track by d.id"></select>

When the view is loaded, it works, I can see the departments matching those bound to the client. However, whenever the selectedRequest.client changes, the source for the department dropdown should change too, but instead it becomes empty.

EDIT

I've changed the child dropdown to :

<select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in departments track by d.id | filter:{clientId: selectedRequest.client.id}"></select>

but this time it loads all the departments in the dropdown, ignoring the filter.

** EDIT 2 **

Changing to :

 <select name="client" ng-model="requestService.selectedRequest.client" ng-options="c as c.name for c in clients track by c.id" required></select>

 <select id="department" ng-model="requestService.selectedRequest.department" ng-options="d.defaultLabel for d in departments  | filter:{clientId: requestService.selectedRequest.client.id}"></select>

Now the source changes correctly when a client is selected. However the initial selection, i.e setting the right department at startup, does not work. That's because I've removed the 'track by id' bit.

Answers:

Answer

the correct way was

 <select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in departments | filter:{clientId: selectedRequest.client.id} track by d.id "></select>

it's just that I hadn't put the filter at the right place... silly mistake.

Answer

It could be that your selectedRequest.client does not refer to the same object in clients array. Try this:

JS:

function testController($scope) {
            $scope.clients = [
             { id: 1, name: "client1", departments: [{ id: 1, defaultLabel: 'department1' }, { id: 2, defaultLabel: 'department2'}] },
             { id: 2, name: "client2", departments: [{ id: 3, defaultLabel: 'department3' }, { id: 4, defaultLabel: 'department4'}] }
            ];

             $scope.selectedRequest = {};
             $scope.selectedRequest.client = $scope.clients[0];//Assign by object reference.
        }

HTML:

<div ng-controller="testController">
        <select name="client" ng-model="selectedRequest.client" ng-options="c.name for c in clients" required></select>
        <select id="department" ng-model="selectedRequest.department" ng-options="d.defaultLabel for d in selectedRequest.client.departments"></select>
    </div>

DEMO

I removed track by to use the default (track by object reference) and ensure that selectedRequest.client refers to objects inside clients

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.