Search code examples
angularjsangularjs-filter

AngularJS - Dropdown Options and Filters


I have two objects, one of users and one of groups. The user object contains the ids of the groups the user is part of, and the groups object contains the id, name and type of group (i.e. hierarchy). Examples below:

users = {
 "user_id_1": {
   id: "user_id_1",
   name: "Steve Smith",
   username: "ssmith1",
   groups: ["group_id_1", "group_id_3",...]
 },
 ...
}

groups = {
 "group_id_1": {
   id: "group_id_1",
   name: "Group 1",
   type: "level_1"
 },
 ...
}

The goal is (at least initially) to have two dropdowns, one for groups and one for users. Selecting a group filters the user list to only show users part of that group.

I've been looking at ui-select to create the dropdowns for me (the input box as part of the dropdown is ideal) or just simple typeahead (but it does lack the dropdown options).

For now I have a simple example for the users dropdown:

<select id="user-dropdown">
 <option ng-repeat="user in $ctrl.users" value="{{ user.id }}">{{ user.name }}</option>
</select>

The problem is that Angular filters only allow filtering of arrays and not objects.

I had the idea of creating two arrays from the objects:

userArray = [user_id_1, user_id_2, ...];
groupArray = [group_id_1, group_id_2, ...];
<option ng-repeat="user in $ctrl.userArray" value="{{ $ctrl.users[user].id }}">{{ $ctrl.users[user].name }}</option>

Even in this case I had problems filtering this list based on the group, as it no longer has the group available in the object.

Any help or thoughts would be appreciated please.


Solution

  • First, reduce your object to an Array and then on select of group dropdown, filter your users. sample code below:

    JS:

    $scope.groupArray = [];
    for(var prop in $scope.groups){
      $scope.groupArray.push($scope.groups[prop]);
    }
    
    var userArray = [];
    for(var prop1 in $scope.users){
      userArray.push($scope.users[prop1]);
    }
    
    
    $scope.onGroupSelect = function(){
      $scope.userList = [];
      $scope.userList = userArray.filter(function(user){
       return user.groups.some(function(group){
          return group === $scope.selectedGroup;
        })
      })
    }
    

    HTML:

    <select ng-model="selectedGroup" ng-change="onGroupSelect()" 
      ng-options="group.id as group.name for group in groupArray">
      </select>
     <br/> 
       <select ng-model="selectedUser">
        <option ng-repeat="user in userList" value="user.id">
          {{user.name}}
        </option>
      </select>
    

    here is the working plunkr for your reference