Prevent multiple select to have the same value

眉间皱痕 提交于 2020-12-13 04:24:05

问题


What it should do

I want to prevent the user to be able to select twice the same option in multiple <select> having the same options.

What it is doing

When selecting a value on the first dropdown, the second won't have the option visible (great). But when selecting a value on the second dropdown (and the first one already have one), it's deleting all the selections. I end up with a selection [null, null].

Am I missing something?

JSFiddle

var app = angular.module('App', []);

app.controller('AppController', function($scope) {
  $scope.selected = [];
  $scope.array = [{
    id: 0,
    title: 'Option0'
  }, {
    id: 1,
    title: 'Option1'
  }, {
    id: 2,
    title: 'Option2'
  }, {
    id: 3,
    title: 'Option3'
  }];
});

app.filter('arrayFilter', function() {
  return (arr, remove, keep) => {
    return arr.filter((item) => {
      for (var i in remove) {
        if (remove[i] == item.id) {
          // If checking current selected, return true
          if (i == keep) {
            return true;
          }
          // Otherwise, current item is selected, return false
          return false;
        }
      }
      return true;
    });
  };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>

<div ng-app="App" ng-controller="AppController">
  <select ng-model="selected[0]" ng-options="option.id as option.title for option in array | arrayFilter:selected:0 track by option.id"></select>
  <select ng-model="selected[1]" ng-options="option.id as option.title for option in array | arrayFilter:selected:1 track by option.id"></select>
  {{ selected }}
</div>

More questions

For this kind of behavior should I use ng-repeat with ng-hide instead of ng-options with a filter?

What's the best practice to have in this case?


回答1:


I finally found a way to make it work with a couple of changes:

  • I had to change the arrayFilter to a filter that returns true or false to show or hide the option. The syntax in HTML changes from option in array | arrayFilter to option in array | filter:arrayFilter.
  • I had to remove track by option.id

I think the problem mainly came from the fact that the old filter was returning a new array which made the ng-model lose its reference to the selected element.

JSFiddle

var app = angular.module('App', []);

app.controller('AppController', function($scope) {
  $scope.selected = [];
  $scope.array = [{
    id: 0,
    title: 'Option0'
  }, {
    id: 1,
    title: 'Option1'
  }, {
    id: 2,
    title: 'Option2'
  }, {
    id: 3,
    title: 'Option3'
  }];
  $scope.arrayFilter = function(selectionArray, position) {
    return function(item, index) {
      return selectionArray.indexOf(item.id) == -1 || item.id == selectionArray[position];
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js"></script>

<div ng-app="App" ng-controller="AppController">
  <select ng-model="selected[0]" ng-options="option.id as option.title for option in array | filter:arrayFilter(selected, 0)"></select>
  <select ng-model="selected[1]" ng-options="option.id as option.title for option in array | filter:arrayFilter(selected, 1)"></select>
  {{ selected }}
</div>


来源:https://stackoverflow.com/questions/41407671/prevent-multiple-select-to-have-the-same-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!