Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 759
Sam Avatar asked Mar 23 '23 02:03

Sam


2 Answers

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.

like image 54
Sam Avatar answered Apr 07 '23 06:04

Sam


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

like image 24
Khanh TO Avatar answered Apr 07 '23 06:04

Khanh TO