2

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

Justin
  • 2,224
  • 2
  • 22
  • 28
  • So you still want see them in the select option fields, but not selectable when they have already been taken by any other select option fields? – ryeballar Dec 18 '14 at 02:22
  • 1
    Are you looking for something like this? **[plunker remove item](http://plnkr.co/edit/BBqnTlxobUpiYxfhyJuj?p=preview)** or **[plunker disabled item](http://plnkr.co/edit/5weXSo9pmovjJDURcpY4?p=preview)** – ryeballar Dec 18 '14 at 12:55
  • I would mark that as the best answer, but it's a comment. – Justin Dec 22 '14 at 02:55
  • then I'll answer it then :) – ryeballar Dec 22 '14 at 05:03

3 Answers3

7

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>

ryeballar
  • 29,658
  • 10
  • 65
  • 74
3

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

Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
  • You are placing view information, the disabled information, into the model. That information does not below in the model. – Enzey Dec 18 '14 at 01:41
  • It would be better to have `ng-disabled="option == model[0]"` – Enzey Dec 18 '14 at 01:44
  • Also to note that not using ng-options means that you will only get back the text between the – Enzey Dec 18 '14 at 01:45
  • Enzey, 'option == model[0]' - this works only for 2 drop downs, question was about 5. I think having a model for disabled is 100% ok since it changes dynamically. You can use – Petr Averyanov Dec 18 '14 at 12:05
1

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/