4

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

Dale K
  • 25,246
  • 15
  • 42
  • 71
qhaut
  • 112
  • 1
  • 2
  • 10
  • Codezilla's solution doesn't remove the empty item when the first pick list changes. Checkout my solution. – zs2020 Aug 06 '13 at 14:38

4 Answers4

7

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];
}
Dale K
  • 25,246
  • 15
  • 42
  • 71
AlwaysALearner
  • 43,759
  • 9
  • 96
  • 78
  • Your solution doesn't remove the empty item when the first pick list changes. – zs2020 Aug 06 '13 at 14:39
  • @SZA I did not deserve a downvote. The last 2 lines ($scope.currentItems = something and $scope.currentItem = something) in the asker's question are completely unnecessary. If you remove them you see that the empty option is visible for all the selections. And may be the asker prefers to keep them over $watch's performance implications. – AlwaysALearner Aug 06 '13 at 14:55
  • @qhaut I have updated my answer to fix the empty option's issue. – AlwaysALearner Aug 06 '13 at 15:06
  • Thank you CodeZilla and all. Works perfectly. Is there a possibilty to remove the empty option from the child's combobox? tx again! – qhaut Aug 06 '13 at 15:18
  • @qhaut Please recheck my answer. – AlwaysALearner Aug 06 '13 at 15:19
1

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

zs2020
  • 53,766
  • 29
  • 154
  • 219
  • 1
    That's a bad idea to add an expensive watcher when you can directly refer to `currentGroup.Items` (as pointed out by [Codezilla](http://stackoverflow.com/a/18082742/2057033)). In order to fill the current item with the first one of the list, you'd better simply use `ngChange` . – Blackhole Aug 06 '13 at 14:24
  • @Blackhole Your solution doesn't remove the empty item when the first ddl changes. – zs2020 Aug 06 '13 at 14:38
  • @zsong if will set item as selected then it wont work as have series od dependent select-box. setting first option as selected wont feed the values in next select box i feed them on ng-change . is there any way to keep some text by default selected always – anam Jul 22 '14 at 12:12
1

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.

Clark Pan
  • 6,027
  • 1
  • 22
  • 18
0

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");
    })
Dale K
  • 25,246
  • 15
  • 42
  • 71
zawhtut
  • 8,335
  • 5
  • 52
  • 76