AngularJS moves items between two picklists

I am trying to move items between two select lists using the code below, but the items are not moving from the list of available clients to the selectedClients list, so can someone check the code below and tell me what I'm missing here? Thanks

<div ng-app> <div ng-controller="testCtrl"> <label for="aclients">Available Clients</label> <select size="5" multiple ng-model="available" ng-options="client.id as client.Name for client in clientsList" style="width: 400px"></select> <input id="moveright" type="button" value="Add Client" ng-click="moveItem(available[0], availableclients,selectedclients)" /> <input id="moverightall" type="button" value="Add All Clients" ng-click="moveAll(availableclients,selectedclients)" /> <input id="move left" type="button" value="Remove Client" ng-click="moveItem(selected[0], selectedclients,availableclients)" /> <input id="moveleftall" type="button" value="Remove All Clients" ng-click="moveAll(availableclients,selectedclients)" /> <label for="sclients">Selected Clients</label> <select size="5" multiple ng-model="selected" ng-options="client.id as client.Name for client in selectedclients" style="width: 400px"></select> <div>Selected Clients IDs: {{selectedclients}}</div> </div> </div> 

Controller:

  app.controller('testCtrl', function testCtrl($scope, clientsService){ $scope.clientsList = clientsService.getClientsList().then( function(response){ $scope.clientsList = response; }, function(status){ console.log(status); } ); $scope.moveItem = function(item, from, to) { console.log('Move item Item: '+item+' From:: '+from+' To:: '+to); //Here from is returned as blank and to as undefined var idx=from.indexOf(item); if (idx != -1) { from.splice(idx, 1); to.push(item); } }; $scope.moveAll = function(from, to) { console.log('Move all From:: '+from+' To:: '+to); //Here from is returned as blank and to as undefined angular.forEach(from, function(item) { to.push(item); }); from.length = 0; }; $scope.availableclients = []; $scope.selectedclients = []; }); 
+6
source share
2 answers

There are several small issues in the template:

  • You move objects from availableclients to selectedclients , but the first choice displays the parameters from clientsList , not from availableclients
  • You are moving identifiers, not objects. Your ng options should just be

     client as client.name for client in availableclients 
  • Your "Delete All" button moves from available to selected, instead of moving from selected to available.

Here is a working plunkr: http://plnkr.co/edit/RYEmpkBjQStoCfgpWPEK?p=preview

 <label for="aclients">Available Clients</label> <select size="5" multiple ng-model="available" ng-options="client as client.name for client in availableclients" style="width: 400px"></select> <input id="moveright" type="button" value="Add Client" ng-click="moveItem(available[0], availableclients,selectedclients)" /> <input id="moverightall" type="button" value="Add All Clients" ng-click="moveAll(availableclients,selectedclients)" /> <input id="move left" type="button" value="Remove Client" ng-click="moveItem(selected[0], selectedclients,availableclients)" /> <input id="moveleftall" type="button" value="Remove All Clients" ng-click="moveAll(selectedclients,availableclients)" /> <label for="sclients">Selected Clients</label> <select size="5" multiple ng-model="selected" ng-options="client as client.name for client in selectedclients" style="width: 400px"></select> 
+14
source

Regarding my comment / question. I really found the answer. So, for those who come here and have the same problem, this is what I found.

When you move an item from one SELECT list to another SELECT list, the angular model in the original list may be lost. To avoid this, changes to each list must be made in a separate call to the $ apply function. The following is an example of abbreviation inside an event handler.

 onClickRight = function (item, from, to) { var self = this; var selecteditem = angular.copy(item); self.$timeout(function () { self.scope.$apply(function () { for (var idx = 0; idx < from.length; idx++) { if (from[idx].value == item.value && from[idx].displayValue == item.displayValue) { item.length = 0; from.splice(idx, 1); break; } }; }); }, 200); self.$timeout(function () { self.scope.$apply(function () { to.push(selecteditem); }); }, 300); }; 

"item" is cloned using angular.copy, so it can be used in the second application angular $ My parameters have 2 properties: value and displayValue I also assign $ timeout and $ scope to the variable "self" in the directive constructor. Hope this helps

0
source

Source: https://habr.com/ru/post/971718/


All Articles