简体   繁体   中英

How to hide select options that are present in another collection

I currently have 2 lists on my page, a total list of all available options, and a selected options list.

When selecting a option from the all available options and adding it to my selected options list i want the option selected to be hidden in the select list for all available options, not removed but hidden.

Here is a link to some code i made that has the basics of the page but not the part about hiding, a java script or angular solution to this is much appreciated.

Link to plunker

<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap@*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
  <script data-require="bootstrap@*" data-semver="4.0.5" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js" integrity="sha256-+f0njwC9E3IT9zDPry5DSIcGdSxQYezBaStQ4L0ZRfU=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>
  <div ng-app="myApp" ng-controller="myCtrl">
    <h1>Page header</h1>
    <div class="list-group">
      <div class="list-group-item" ng-show="!selectedWords.length">
        <i>No selected words</i>
      </div>
      <div ng-repeat="word in selectedWords" class="list-group-item">{{word}}</div>
    </div>
    <div class="input-group">
      <select ng-model="selectedWord" class="form-control" required="required">
        <option ng-repeat="word in allWords" value="{{word}}">{{word}}</option>
      </select>
      <span class="input-group-btn">
          <button class="btn btn-default" type="button" ng-click="addWord()">Add</button>
        </span>
    </div>
  </div>
</body>

</html>

JS file:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.allWords = ["Banana", "Orange", "Apple", "Mango"];
  $scope.selectedWords = [];
  $scope.addWord = function() {
    $scope.selectedWords.push($scope.selectedWord);
  }
});

One way you can do it is with a custom filter like so:

Note that this solution does not ever modify the allWords array, it simply limits (on the view) which ones are visible based on the state of the selectedWords array, which makes adding the items back into the list as simple as removing the word from the selectedWords array.

UPDATE -- Added removeWord() functionality (also included font awesome icon library for remove word icon)

UPDATE 2 -- loading selectedWords from json file on page load

Working DEMO

 var app = angular.module('myApp', []); app.filter("unselectedWords", function() { return function(list, selectedWords) { var unselectedWords = list.slice().filter(function(elem) { return selectedWords.indexOf(elem) === -1; }); return unselectedWords; }; }); app.controller('myCtrl', function($scope) { $scope.allWords = ["Banana", "Orange", "Apple", "Mango"]; $scope.selectedWords = []; $scope.addWord = function(word) { if (word != undefined && word !== "" && $scope.selectedWords.indexOf(word) === -1) { $scope.selectedWords.push(word); } }; $scope.removeWord = function (word) { $scope.selectedWords.splice($scope.selectedWords.indexOf(word), 1); }; }); 
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <link data-require="bootstrap@*" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" /> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl"> <h1>Page header</h1> <div class="list-group"> <div class="list-group-item" ng-show="!selectedWords.length"> <i>No selected words</i> </div> <div ng-repeat="word in selectedWords" class="list-group-item">{{word}} <span style="position: absolute; right: 10px; top: 12px; cursor: pointer;" ng-click="removeWord(word)" title="Remove Word"> <i class="fa fa-times fa-lg" style="color: red"></i> </span> </div> </div> <div class="input-group"> <select ng-model="selectedWord" class="form-control" required="required"> <option ng-repeat="word in allWords | unselectedWords:selectedWords" value="{{word}}">{{word}}</option> </select> <span class="input-group-btn"> <button class="btn btn-default" type="button" ng-click="addWord(selectedWord)">Add</button> </span> </div> </div> </body> 

Here's one way: http://plnkr.co/edit/uCrU28z7WzkopNlx2LlK?p=preview

Change your markup by setting the value of the select to the index instead of the value:

<option ng-repeat="word in allWords" value="{{$index}}">{{word}}</option>

That way when you want to remove the word from the list you don't have to go searching for it using string comparison:

  $scope.addWord = function() {
    $scope.selectedWords.push($scope.allWords[$scope.selectedWord]);
    removeWord($scope.selectedWord);
  };

  function removeWord(index) {
    $scope.allWords.splice(index,1);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM