1

How do you clear an array with selected values so that values can return to the select?

I have a people array. The people array values are available in select. When I choose names, they are transferred to the multipleDemo array. And you can not reselect them from select because they disappear and are moved to the multipleDemo array. With the Delete button I have to delete all elements from the multipleDemo array (except the first element) into the people array. So that you can again choose a name from the select. Error in function $clearTag.

Expecting behavior: Example:

  1. Select: Wladimir
  2. Appear tag Wladimir
  3. Select Wladimir (You can't choose Wladimir because he is already chosen)
  4. Click Delete. Cut elements(tags) with multipleDemo array and put them in array people
  5. You can again select Wladimir

Here is my code: http://plnkr.co/edit/TPZjXkkSRrIc5ApzP07F?p=preview

index.html

<!DOCTYPE html>
<html lang="en" ng-app="demo">
<head>
  <meta charset="utf-8">
  <title>AngularJS ui-select</title>

  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
  <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">

  <!-- ui-select files -->
  <script src="select.js"></script>
  <link rel="stylesheet" href="select.css">

  <script src="demo.js"></script>

  <!-- Select2 theme -->
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">

  <style>
    body {
      padding: 15px;
    }

    .select2 > .select2-choice.ui-select-match {
      /* Because of the inclusion of Bootstrap */
      height: 29px;
    }

    .selectize-control > .selectize-dropdown {
      top: 36px;
    }
  </style>
</head>
<body ng-controller="DemoCtrl">
    
  <h3>Array of strings</h3>
  <button ng-click='clearTag()'>Delete</button>
  <ui-select tagging tagging-label="new tag" multiple ng-model="multipleDemo" 
  on-select="OnClickSelect($item)" on-remove="OnRemoveSelect($item)"
  theme="select2" ng-disabled="disabled" style="width: 300px;">
    <ui-select-match placeholder="Select name...">{{$item.name}}</ui-select-match>
    <ui-select-choices  repeat="item in people | filter:$select.search">
      {{item.name}}
    </ui-select-choices>
  </ui-select>
  <p>Selected: {{multipleDemo}}</p>
  <hr>  

</body>
</html>

demo.js

app.controller('DemoCtrl', function($scope, $http, $timeout) {
  $scope.multipleDemo =[];
    $scope.people = [
    { name: 'Adam',      email: 'adam@email.com',      age: 12, country: 'United States' },
    { name: 'Amalie',    email: 'amalie@email.com',    age: 12, country: 'Argentina' },
    { name: 'Estefanía', email: 'estefania@email.com', age: 21, country: 'Argentina' },
    { name: 'Adrian',    email: 'adrian@email.com',    age: 21, country: 'Ecuador' },
    { name: 'Wladimir',  email: 'wladimir@email.com',  age: 30, country: 'Ecuador' },
    { name: 'Samantha',  email: 'samantha@email.com',  age: 30, country: 'United States' },
    { name: 'Nicole',    email: 'nicole@email.com',    age: 43, country: 'Colombia' },
    { name: 'Natasha',   email: 'natasha@email.com',   age: 54, country: 'Ecuador' },
    { name: 'Michael',   email: 'michael@email.com',   age: 15, country: 'Colombia' },
    { name: 'Nicolás',   email: 'nicolas@email.com',    age: 43, country: 'Colombia' }
  ];

  $scope.OnClickSelect=function(item)
  {
   $scope.multipleDemo.push(item.name);
  }
  
  $scope.OnRemoveSelect = function(item) { 
   var index = $scope.people.indexOf(item.name);
   $scope.people.splice(index, 1); 
  }
  
  $scope.clearTag = function() {
    for(var i =0; i < $scope.multipleDemo.length; i++) {
      $scope.multipleDemo.splice($scope.multipleDemo[i], 1000);
      $scope.people.push($scope.multipleDemo[i]);
    }
  }
Community
  • 1
  • 1
  • 1
    I don't understand the behavior you are expecting. By the way your **clearTag** function won't be called because you declare it as *$scope* in js but call it *$ctrl* in html – IsraGab Apr 14 '19 at 19:27
  • Function clearTag. Cut out elements using the splice method wants to put back in the people array –  Apr 14 '19 at 20:13
  • You should read up on how the [`ngController`](https://docs.angularjs.org/api/ng/directive/ngController) directive works. You either inject `$scope` into your controller, as you've shown, and access scope variables without an object reference, or you use something like `ng-controller="controller as $ctrl"` and use the `$ctrl.clearTag()` syntax. You're currently trying to use both. You likely have errors in your console regarding that; if you'd like further help, please show those in your question. – Heretic Monkey Apr 14 '19 at 20:26
  • I deleted $ctrl. I have ng-click="clearTag()". I don't have in console any errors. –  Apr 14 '19 at 20:32

1 Answers1

0

Angular-UI-Select Common Issues

ng-model not working with a simple variable on $scope

You cannot write:

WRONG

<ui-select ng-model="multipleDemo"> <!-- Wrong -->
  [...]
</ui-select>

You need to write:

<ui-select ng-model="vm.multipleDemo"> <!-- Correct -->
  [...]
</ui-select>

For more information, see


Update

vm.multipleDemo doesn't work; I try $parent.multipleDemo - it works. I don't understand $parent. Why it works?

For vm.multipleDemo to work, the controller must initialize the vm object:

app.controller('DemoCtrl', function($scope, $http, $timeout) {
    $scope.vm = { multipleDemo: [] };

New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the [data hiding] problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.

What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

Avoid using $parent to fix a data hiding problem. It is a brittle solution as there can be more than one level of scope heirarchy between the controller and the ui-select directive. I consider the use of $parent to be a code smell, a symptom of a deeper problem.


Update #2

When I can use $ctrl in view and this in controller?

If the controller is instantiated with "controller as" syntax:

<body ng-controller="DemoCtrl as $ctrl">

    <ui-select ng-model="$ctrl.multipleDemo">
       <!-- -->
    </ui-select>

Then there is no need to use $scope:

app.controller('DemoCtrl', function($http) {
    this.multipleDemo =  [];

And it avoids the data hiding problem.

For more information, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • vm.multipleDemo doesn't work; I try $parent.multipleDemo - it works. I don't understand $parent. Why it works? –  Apr 15 '19 at 07:12
  • When I can use '$ctrl' in view and 'this' in controller? –  Apr 15 '19 at 09:10
  • Is it possible to iterate over the array, excluding the first element (omit the first element in the array)? –  Apr 16 '19 at 09:57
  • That should be asked as a [new question](https://stackoverflow.com/questions/ask). – georgeawg Apr 16 '19 at 16:01