Search code examples
angularjsangularjs-scopeangularjs-ng-repeatangular-ng-if

Dynamic dropdown using ng-repeat in Angular


My application gives users the option to choose from several dropdown menus and the third menu should be dynamic depending on the selection from the previous two menus.

I am using ng-repeat and ng-if to set the condition like this

// First dropdown menu
<select ng-model="letter" class = "form-control">
    <option ng-repeat= "letter in letters" value = "letter">{{letter}}</option>
</select>

<br>

// second dropdown menu
<select ng-model="number" class = "form-control">
    <option ng-repeat = "number in numbers" value = "number">{{number}}</option>
</select>

<br>

// third dropdown menu
<select ng-model="color" class="form-control">
    <option ng-repeat="A1_color in A1_colors" ng-if= "letter = A & number = 1" value="{{A1_color}}">{{A1_color}}</option>
</select>

...

<select ng-model="color" class="form-control">
    <option ng-repeat="B2_color in B2_colors" ng-if= "letter = B & number = 2" value="{{B2_color}}">{{B2_color}}</option>
</select>

In my controller, I have the lists like this

$scope.letters = {'A', 'B'};
$scope.numbers = {'1', '2'};

$scope.A1_colors = {'red', 'pink'};
$scope.A2_colors = {'blue', 'black'};
$scope.B1_colors = {'yellow', 'orange'};
$scope.B2_colors = {'white', 'black'};

So if the user selects 'A' from the first menu and '2' from the second menu, he should see the options for 'A2_colors' in the third menu. What is the right way to do this?


Solution

  • The "right way" is pretty subjective. Is this just a smaller example of what will be a larger collection of letters, numbers and colors? Here is one way you could approach it where you won't have to create a whole bunch of <select></select> elements that you show or hide.

    JS:

    angular.module('app', [])
        .controller('ctrl', function($scope) {
            $scope.letters = ['A', 'B'];
            $scope.numbers = ['1', '2'];
            var colors = {
                'A1': ['red', 'pink'],
                'A2': ['blue', 'black'],
                'B1': ['yellow', 'orange'],
                'B2': ['white', 'black']
            };
    
            $scope.colorSelection = [];
    
            $scope.setColorSelection = function() {
                if ($scope.selectedLetter && $scope.selectedNumber) {
                    $scope.colorSelection = 
                        colors[$scope.selectedLetter + $scope.selectedNumber];
                }
            }
        });
    

    HTML:

    <div ng-app="app" ng-controller="ctrl">
        <select ng-model="selectedLetter" 
                ng-change="setColorSelection()" 
                ng-options="letter as letter for letter in letters">
        </select>
        <select ng-model="selectedNumber" 
                ng-change="setColorSelection()" 
                ng-options="number as number for number in numbers">
        </select>
        <select ng-model="selectedColor" 
                ng-if="colorSelection.length" 
                ng-options="color as color for color in colorSelection">
        </select>
    </div>