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?
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With