0

I'd like the active state of items in one drop-down list to be contingent on properties from a second model:

angular.module('mainApp')
  .controller('MainCtrl', function($scope) {
  $scope.departments = [
    {id:0, name: 'Dry Goods'},
    {id: 1, name:'Frozen Food'},
    {id: 2, name:'Electronics'}
  ];
  $scope.categories = [
    {id: 0, name: 'cereal', departmentId: 0},
    {id: 1, name: 'cookies', departmentId: 0},
    {id: 2, name: 'televisions', departmentId: 2}
  ];
});

and the drop-downs:

<select ng-model="department" ng-options="department.name for department in departments" ng-change="changeDepartment()">
  <option value="">Department</option>
</select>

<select ng-model="category" ng-options="category.name for category in categories" ng-change="changeCategory()">
  <option value="">Category</option>
</select>

I'd like the Department drop-down to display all three items, but only 'Dry goods' and 'Electronics' should be selectable because there are items in Category that map to Department through the departmentId property. Frozen food should be grayed out.

Plunker : http://plnkr.co/edit/c7rZ05qqRCnB7L0ANgZ4?p=preview

Thanks in advance.

Josep
  • 12,926
  • 2
  • 42
  • 45
Chris
  • 115
  • 9

1 Answers1

1

Just use the $filter 'filter' in your second select, fike this:

  <select ng-model="category" ng-options="category.name for category in categories|filter:{departmentId:department.id}" ng-change="changeCategory()">
    <option value="">Category</option>
  </select>

Example

UPDATE

Since ng-options doesn't provide a functionality for indicating which values should be disabled, you only have 2 options:

  1. Create a custom directive that will give you that option, this is not an easy task because that directive should be watching for the collection of the ng-select and the collection or selected value of the other select, in other words this: ng-options with disabled rows won't work for you.

  2. Build your select with an ng-repeat, much easier, like this:

.

   <div ng-controller='MainCtrl'>
    <div class="btn-group">
      <select ng-model="departmentID" ng-change="changeDepartment()">
            <option value="">Category</option>
            <option ng-repeat="department in departments" value="{{department.id}}" ng-disabled="(categories|filter:{departmentId:department.id}).length==0">{{department.name}}</option>
      </select>
    </div>
    <div class="btn-group">
      <select ng-model="categoryID" ng-change="changeCategory()">
            <option value="">Category</option>
            <option ng-repeat="category in categories" value="{{category.id}}" ng-disabled="departmentID!=category.departmentId">{{category.name}}</option>
      </select>
    </div>
   </div>

Example

Community
  • 1
  • 1
Josep
  • 12,926
  • 2
  • 42
  • 45
  • Thanks for the tip, I'll look into using one model to filter another model. Your example doesn't seem to be filtering though and has the same result as mine. If I get it working, would it deactivate the items from Department that don't have a corresponding catagory.departmentId value, or would they just not show up in the Department list? – Chris Oct 01 '14 at 16:38
  • @Chris my example doesn't behave like yours and it certainly has a different result than yours, in my example when you select an item in the first 'select' the items of the second select get filtered accordingly... When you select "Dry foods" the second select will show "cereal" and "cookies", if you select "Electronics" the second one will show "televisions".... – Josep Oct 01 '14 at 16:49
  • My apologies, I didn't notice that change you made because it doesn't have the effect I desire. I want the inverse effect, or something akin to it. **Department** items should be filtered by categories that have a corresponding departmentId value. I want all items to display in both lists. The only items in **Department** that should be active, are items that have an id that exists as a category.departmentId value. So in the Department drop-down, all three items should be present, but only **Dry Goods** and **Electronics** should be selectable. Make sense? – Chris Oct 01 '14 at 17:03
  • @Chris I get it now, I will update my answer once I get home, thanks for the explanation! – Josep Oct 01 '14 at 20:52
  • @Chris I just updated my answer, please have a look at it, thanks! – Josep Oct 02 '14 at 00:28