qhaut
qhaut

Reputation: 112

AngularJS, Populating dependent Combobox

What I am trying to achieve is to populate a child combobox with items which depend on a 'parent' combobox.

To clarify the problem, I have created a Fiddle under this link.

The combobox 'items' should populate every time the combobox 'group' has changed.

Controller:

function Controller( $scope ) {    
    var groups = [ ]; // ommitted for the sake of clarity
    
    $scope.groups = groups;                 // <- linked to cboGroup
    $scope.currentGroup = groups[0];        // <- should be updated from combobox
    $scope.currentItems = $scope.currentGroup.Items;  // <- linked to cboItems
    $scope.currentItem = $scope.currentItems[0];      // <- should be updated from cboItems
}

View

<select data-ng-model="currentGroup" data-ng-options="group.Name for group in groups"></select>
<select data-ng-model="currentItem" data-ng-options="item.Name for item in currentItems"></select>

I can't bring this to life declaratively. This should work without magic JavaScript - shouldn't it?

Thank you for your support

Upvotes: 4

Views: 13691

Answers (4)

AlwaysALearner
AlwaysALearner

Reputation: 43947

You should refer currentGroup to populate the options inside items combobox:

<select data-ng-model="currentItem" data-ng-options="item.Name for item in currentGroup.Items"></select>

You don't need $scope.currentItems at all. So just update the last 2 lines inside the controller to:

$scope.currentItem = $scope.currentGroup.Items[0];  

Now to remove the empty option, use super easy and light-weight ng-change:

<select data-ng-model="currentItem" data-ng-options="item.Name for item in currentGroup.Items" ng-change="groupChanged()"></select>

Define the corresponding change handler in the controller:

$scope.groupChanged = function(){
    $scope.currentItem = $scope.currentGroup.Items[0];
}

Upvotes: 7

zawhtut
zawhtut

Reputation: 8561

There is other solution to this kind of issues. That is to broadcast.

Do broadcast after you got the data. In this example data came from Ajax call.

$http.get('/SampleProgram/get_all_users').success(function(rsList){
       $scope.users =  rsList;
       $scope.$broadcast('I got all the users');
    });

There should be listeners who always keeps their ears open for your broadcast message.

$scope.$on('I got all the users', function () {
        alert("Hey All the users are here already let's make another ajax call with those users");
    })

Upvotes: 0

zs2020
zs2020

Reputation: 54543

You can add a watcher to the controller like this. You can also remove the empty item when you pick different value of the first drop down list.

$scope.$watch('currentGroup', function () {
    $scope.currentItems = $scope.currentGroup.Items;
    $scope.currentItem = $scope.currentGroup.Items[0];
});

Demo

Upvotes: 1

Clark Pan
Clark Pan

Reputation: 6027

This should be what you're after:

http://jsfiddle.net/TsxTU/1/

How this works is its using the select as label for item in group syntax. So for the first select box, whatever the user selects will become the object bound to currentGroup. A similar thing is done for currentItem

We can then, optionally, use a $watch expression to be notified of that update and ensure that currentItem updates to the first item in the new group's Items array.

Upvotes: 1

Related Questions