Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling moving of item across lists in angular-ui sortable?

I am using angular-ui sortable version 1.2

I want to handle the move of an item from one list to another, and update the back-end accordingly.

jquery-ui-sortable defines a bunch of events, including the receive event

From within that event handler, I cannot find a way to access the angular model item which was moved, and its new parent list.

See this codepen sample. You can see that I can access the item via the scope() in the update event, but not in the receive event.

Any suggestions for a way to handle these moves? either via the receive event or otherwise?

like image 606
sagism Avatar asked Jan 17 '14 09:01

sagism


1 Answers

Reorder the items in one list

UI sortable behaves intuitive if you have one list of items and just want to reorder the list. In this case you do the following if you have an array of objects in your controller like this:

$scope.yourObjects = [
   {title:'Alabama'}, {title:'Ohio'}, {title:'Colorado'}   
];

in your html you may create a list of these items by using ng-repeat:

<ul ui-sortable="sortableOptionsA" class="list items-container" ng-model="yourObjects">
   <li class="item sortable" ng-repeat="item in yourObjects">{{item.title}}</li>
</ul>

where sortableOptions is:

$scope.sortableOptionsA = {
   stop : function(e, ui) {
      var item = ui.item.scope().item;
      var fromIndex = ui.item.sortable.index;    
      var toIndex = ui.item.sortable.dropindex;
      console.log('moved', item, fromIndex, toIndex);
   }
};

As you can see, in the stop function we have access to all relevant information we need to be informed about the movement.

Connect 2 list of items

Now the problem get's a little bit complicated. UI Sortable gives us no information about the drop-targets that we can use directly in any way. If we move one item from one list to another list the following events are fired:

start: We have access to the item that will be moved including the scope of this item.

update: We have access to the item that is moved including the scope of this item.

Now the item is deleted from it's source list

removed: The item was removed from the source list. The scope is no longer valid (e.g. undefined).

received: The item is about to be dropped in the second list. scope is still undefined, we have only access to the sender e.g. the drag source.

Now the item is inserted in the target list.

update: The item is dropped at the target list. but we have no access to the item scope nor does there a target object exist in the event objects. The jQuery UI Sortable did not provide these information and the angular wrapper did not expose the target model in any way :(

stop: If all steps of the drag'n'drop process are done, the stop event is fired. But we have also no access to the items target scope or the target list.

What can we do if we want to get informed about a movement and which item was moved to what kind of list?

The item that was moved is accessible by ui.item.sortable.moved in the stop event. This is our item that was moved.

Which list is the drop-target can be determined by Angular's $watch function. We just listen to changes to the lists and know, which list was modified. One caveat: the source and the target list are changing, but the target list is changed at last (see the above event order). If we listen to the changes in this way:

$scope.dropTarget = null;
$scope.$watchCollection('lists[0].items', function() {
   console.log('watch 0');
   $scope.dropTarget = $scope.lists[0];
});
$scope.$watchCollection('lists[1].items', function() {
   console.log('watch 1');
   $scope.dropTarget = $scope.lists[1];
});

we have all information to get to know wich item was moved to what kind of list and what are the from and the to index:

stop:function(e, ui){
  var item = ui.item.sortable.moved;
  var fromIndex = ui.item.sortable.index;
  var toIndex = ui.item.sortable.dropindex;
  console.log(item, fromIndex, toIndex, $scope.dropTarget);
},

PLUNKR with a lot of debug code that shows what kind of information is available during the drag'n'drop process.

Remark: if you move one item from the 'Connected lists' to 'One sortable list' the log output is wrong - because there is no listener to the 'One sortable list' list!

like image 155
michael Avatar answered Sep 19 '22 10:09

michael