Search code examples
angularjsng-options

Angular: Drop Down Item active based on model dependency


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.


Solution

  • 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