Justin
Justin

Reputation: 2404

Disabled selected item in Angular for other Select Option Fields of the same Items

I've been struggling on this for a while... I'm currently using Angular.

Let's say we have five select option fields and that we are iterating through the same list for each one.

Our options are:

$scope.items = [one, two, three, four, five];

If I choose one, how would I disable the selected option for the remaining select option fields? And if I go to another select option field and select an available item, it then disables that item for all the other fields.

Any help or even guidance on how to do this would be appreciated. Thanks

Upvotes: 2

Views: 6584

Answers (3)

ryeballar
ryeballar

Reputation: 30118

There are two possible solutions that you may want, and it depends on what kind of disabling your specs require.

  1. Disable by removing the items that are already selected from other select elements. This solution requires a filter that removes the items that has already been selected except for the current item that the current select tag has selected.

DEMO

Javascript

  .controller('Ctrl', function($scope) {

    $scope.items = [1,2,3,4,5];
    $scope.data = [];

  })

  .filter('arrayDiff', function() {
    return function(array, diff) {
      var i, item, 
          newArray = [],
          exception = Array.prototype.slice.call(arguments, 2);

      for(i = 0; i < array.length; i++) {
        item = array[i];
        if(diff.indexOf(item) < 0 || exception.indexOf(item) >= 0) {
          newArray.push(item);
        }
      }

      return newArray;

    };
  });

HTML

<select 
  ng-repeat="(modelIndex, itemValue) in items track by modelIndex"
  ng-model="data[modelIndex]"
  ng-options="item for item in $parent.items | arrayDiff:data:data[modelIndex]">
  <option value="">Select Number</option>
</select>

  1. Disable by setting a disabled property to the option items, this is actually a complex way of solving the problem as it does not use the standard angular select ng-option syntax. By using an ng-repeat to iterate over items and add an ng-disabled expression that evaluates the current selected item against other selected items from other select elements.

DEMO

Javascript

  .controller('Ctrl', function($scope) {

    this.items = ['1', '2', '3', '4', '5'];
    this.data = [];

  })

  .filter('hasIntersection', function() {
    return function(item, array) {
      return array.indexOf(item) >= 0;
    };
  });

HTML

<select
  ng-repeat="(selectIndex, itemValue) in Demo.items"
  ng-model="Demo.data[selectIndex]">

  <option value="" ng-selected="Demo.data[selectedIndex] == item">
    Select Number  
  </option>

  <option ng-repeat="item in Demo.items"
          value="{{item}}"
          ng-disabled="item | hasIntersection:Demo.data"
          ng-selected="Demo.data[selectIndex] == item">
    {{item}}
  </option>

</select>

Upvotes: 7

Petr Averyanov
Petr Averyanov

Reputation: 9486

ng-disabled is your friend here, however I think you may face some problems with dynamic selects in IE. http://plnkr.co/edit/Ca6l2sHjN2PRykidm9kx?p=preview

Upvotes: 3

Jason Sylvester
Jason Sylvester

Reputation: 36

You can use ng-disabled.

<select ng-options="item in items" ng-model="selectedItem" ng-disabled="selectedItem"></select>

Working example here: http://jsfiddle.net/astrojason/4njwhdua/

Upvotes: 1

Related Questions