Callum Callum - 4 months ago 14
AngularJS Question

filter dropdown by another dropdown

I'm trying to use the value of one dropdown to then filter the values displayed in the next dropdown. The dropdowns are populated with data from multiple JSON files (as shown below).

The desired result is to filter the Templates by Applications.Name, as you can see templates also has Application.Name inside of it, when the first dropdown is selected I would like the results to first be filtered to check if templates.Application.Name == selectedTestScript.Application (which is the ng-model of the first dropdown).

Could anybody point me in the direction of some useful resources or better yet explain where I'm growing wrong? Any help is greatly appreciated.

Applications JSON:

{
"Applications": [
{"Id": 1, "Name":"Deep Thought"},
{"Id": 2, "Name":"Agent Smith"},
{"Id": 3, "Name":"Glados"},
{"Id": 4, "Name":"Jarvis"}
]

}


Templates JSON:

{
"Templates": [
{"Id": 1, "Name":"Deep Thought template 1", "Application":{"Name": "Deep Thought", "Id": 1}},
{"Id": 2, "Name":"Deep Thought template 2", "Application":{"Name": "Deep Thought", "Id": 1}},
{"Id": 3, "Name":"Agent Smith template 1", "Application":{"Name": "Agent Smith", "Id": 2}},
{"Id": 4, "Name":"Agent Smith template 2", "Application":{"Name": "Agent Smith", "Id": 2}},
{"Id": 5, "Name":"Glados template 1", "Application":{"Name": "Glados", "Id": 3}},
{"Id": 6, "Name":"Glados template 2", "Application":{"Name": "Glados", "Id": 3}},
{"Id": 7, "Name":"Jarvis template 1", "Application":{"Name": "Jarvis", "Id": 4}},
{"Id": 8, "Name":"Jarvis template 2", "Application":{"Name": "Jarvis", "Id": 4}}
]

}


HTML:

<div class="panel-body">
<div>
<label for="appName" class="control-label col-xs-3">Application:</label>
<div class="col-xs-9">
<select id="appName" class="form-control col-sm-4" placeholder="Please select an application" ng-model="selectedTestScript.Application" ng-options="application.Name for application in applications" />
</div>
</div>
<div>
<label retinafor="importActions" class="control-label col-xs-3">Templates:</label>
<div class="col-xs-9">
<div class="input-group">
<select class="form-control" placeholder="Please select an action" ng-model="selectedTemplate" ng-options="template.Name for template in templates | filter :{templates : templatesFilter}" />
<div class="input-group-btn">
<button type="button" class="btn btn-default btn-general" ng-click="importTemplate(selectedTemplate); actionList = true"><i class="fa fa-plus iconswhite"></i> Import</button>
</div>
</div>
</div>
</div>
</div>


Controller:

$scope.templatesFilter = function (application) {
return templates.Application.Name === $scope.selectedTestScript.Application;
}

Answer

You don't need to build your own filter to achieve this.

You can simply change

this:

<select class="form-control" placeholder="Please select an action" ng-model="selectedTemplate" ng-options="template.Name for template in templates | filter :{templates : templatesFilter}" />

for:

<select class="form-control" placeholder="Please select an action" ng-model="selectedTemplate" ng-options="template.Name for template in templates | filter: { Name: selectedTestScript.Application.Name }"></select>

Demo:

angular.module('app', [])
  .controller('mainCtrl', function($scope) {
    $scope.applications = [  
       {  
          "Id":1,
          "Name":"Deep Thought"
       },
       {  
          "Id":2,
          "Name":"Agent Smith"
       },
       {  
          "Id":3,
          "Name":"Glados"
       },
       {  
          "Id":4,
          "Name":"Jarvis"
       }
    ];

    $scope.templates = [  
       {  
          "Id":1,
          "Name":"Deep Thought template 1",
          "Application":{  
             "Name":"Deep Thought",
             "Id":1
          }
       },
       {  
          "Id":2,
          "Name":"Deep Thought template 2",
          "Application":{  
             "Name":"Deep Thought",
             "Id":1
          }
       },
       {  
          "Id":3,
          "Name":"Agent Smith template 1",
          "Application":{  
             "Name":"Agent Smith",
             "Id":2
          }
       },
       {  
          "Id":4,
          "Name":"Agent Smith template 2",
          "Application":{  
             "Name":"Agent Smith",
             "Id":2
          }
       },
       {  
          "Id":5,
          "Name":"Glados template 1",
          "Application":{  
             "Name":"Glados",
             "Id":3
          }
       },
       {  
          "Id":6,
          "Name":"Glados template 2",
          "Application":{  
             "Name":"Glados",
             "Id":3
          }
       },
       {  
          "Id":7,
          "Name":"Jarvis template 1",
          "Application":{  
             "Name":"Jarvis",
             "Id":4
          }
       },
       {  
          "Id":8,
          "Name":"Jarvis template 2",
          "Application":{  
             "Name":"Jarvis",
             "Id":4
          }
       }
    ];
  });
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="mainCtrl">
  <div class="panel-body">
    <div>
      <label for="appName" class="control-label col-xs-3">Application:</label>
      <div class="col-xs-9">
        <select id="appName" class="form-control col-sm-4" placeholder="Please select an application" ng-model="selectedTestScript.Application" ng-options="application.Name for application in applications"></select>
      </div>
    </div>
    <div>
      <label retinafor="importActions" class="control-label col-xs-3">Templates:</label>
      <div class="col-xs-9">
        <div class="input-group">
          <select class="form-control" placeholder="Please select an action" ng-model="selectedTemplate" ng-options="template.Name for template in templates | filter: { Name: selectedTestScript.Application.Name }"></select>
          <div class="input-group-btn">
            <button type="button" class="btn btn-default btn-general" ng-click="importTemplate(selectedTemplate); actionList = true"><i class="fa fa-plus iconswhite"></i> Import</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>

</html>