[Angular JS] Setting a combobox based on selection of another one

This might be my first post which touch Angular JS, and wanted to let you guys know that I too joined the backend to frontend club! Currently Angular JS is powering https://browserperfdash.igalia.com/ with Django REST at the backend – and I think its super fast, easy to develop and allows for a cleam responsive UI – WOW is the word.

Problem
You have a data model, which looks something like:

bots = [{ 'bot1' : {'platform': "Linux", id:1}}, { 'bot2' : {'platform': "Windows", id:2}}];
platforms = [{ 'name' :'Linux', 'id' :1},{ 'name' :'Windows', 'id' :2}, { 'name' :'MacOSuX', 'id' :3}];     

You have a select box bots and another select box Platforms and you need the following logic to happen:

  1. When no bot is selected,the Platforms combo should show All all the platform options
  2. When a bot is selected, it should force the Platform combo to show the platform property of bot selected, and should disable them to make no further changes.

Solution
You will need the following Angular script to make this work. Add this to your scripts.js or wherever place and include it in your html file.

app.controller('AppController', function($scope) {
    $scope.bots = [{ 'name': 'bot1', 'platform': "Linux", id:1}, { 'name': 'bot2', 'platform': "Windows", id:2}];
    $scope.platforms = [{ 'name' :'Linux', 'id' :1},{ 'name' :'Windows', 'id' :2}, { 'name' :'MacOSuX', 'id' :3}];     
});

see that you can even add this directly to the html file with the tag. Now you can add the following to the HTML file so that the data gets correctly rendered to the browser.

<div class="form-group">
  <label for="bot">Bot</label>
  <select name="bot" class="form-control" ng-model="selectedBot"
	  ng-options="bot.name for bot in bots">
      <option value="">--All bots--</option>
  </select>
</div>
<div class="form-group">
  <label for="platform">Platform</label>
  <select name="platform" class="form-control" ng-model="selectedPlatform" ng-disabled="selectedBot">
      <option value="">--All platforms--</option>
      <option ng-repeat="x in platforms" value="{{ x.name }}">{{ x.name }}</option>
      <option value="{{ selectedBot.platform }}" ng-selected="selectedBot" ng-show="selectedBot">
	  {{ selectedBot.platform }}</option>
  </select>
</div>

How it works?

  • The {{ x.name }} makes sure that all the platforms are shown initially making sure our condition (1) above.
  • The {{ selectedBot.platform }} makes sure that when the bot select is clicked, this option value is set for the combo box – adding to (2) above.
  • The ng-selected="selectedBot" ng-show="selectedBot" makes sure that the combo gets disabled when someone selects in some value for bots contributing to (2) above
  • You can see the dropdowns live in action at https://browserperfdash.igalia.com/ and do take a look and comment if something seems weird.

    Update: It seems like there was a problem with this approach as the selectedPlatform is not getting set correctly, even though the combo gets set. You can fix this by
    adding in the following action on ng-change on the select combo

    <select name="bot" class="form-control" ng-model="selectedBot"
          ng-options="bot.name for bot in bots" ng-change="updateOtherCombos()">
      <option value="">--All bots--</option>
    </select>
    

    and now defining the function updateOtherCombos() to your controllers.js

    app.controller('AppController', function($scope) {
        $scope.bots = [{ 'name': 'bot1', 'platform': "Linux", id:1}, { 'name': 'bot2', 'platform': "Windows", id:2}];
        $scope.platforms = [{ 'name' :'Linux', 'id' :1},{ 'name' :'Windows', 'id' :2}, { 'name' :'MacOSuX', 'id' :3}];     
        $scope.updateOtherCombos = function () {
          if ( $scope.selectedBot ) {
    	  $scope.selectedPlatform = $scope.selectedBot.platform;
    	  $scope.selectedCPU = $scope.selectedBot.cpu;
    	  $scope.selectedGPU = $scope.selectedBot.gpu;
          }
       };
    });
    
    Advertisements