Problem:
I'm trying to recreate the Draggable + Sortable functionality from jQuery and can't get the dropped element to go into my array of objects.
I want to drag a $.draggable() button into a $.sortable() list.. I want the button to represent an object with properties (could be assoc array, or the object itself) and when I drop it in my list I want it to put itself into the the array at the position it was dropped at.
Just to be clear: I have an array of potential objects in a menu to the left. On the right I use $http to call to my API to retrieve a form that has fields all held in $scope. I want that potential object (like a textarea) to be dropped into that form's fields at the position dropped.
The jquery bit is straightforward but the non existent object to position in $scope array is the problem.
What I've tried:
I was close with mixing combing ui-sortable and $.draggable directive wrapper but my code isn't working very well.
Examples:
- KnockoutJS Example: http://bit.ly/15yrf8X
- jQuery demo: http://jqueryui.com/draggable/#sortable
Update 1:
I have made progress with a ui-sortable like directive combined with a directive that wraps $.draggable(), kinda ugly but works.
Update 2:
I have it working now but I grab the index from jquery and use php to slice it into that position and then reload the entire list. Talk about lame there must be a better way.
Update 3:
Here is a working example modularized for anyone's app.
There is no angular-magic that can help you find the position of a new or moved element, but it's easy to do with jQuery. I've created an example of the jQueryUI-demo wrapping sortable and draggable in directives:
http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview
Value of my
my-draggable
is the id to the correspondingmy-sortable
-element. my-draggable is otherwise pretty straight forward:In
my-sortable
I listen to thedeactivate
event which indicates that an element has been dropped.from
is the position of the element in the array that is the source of ng-repeat. ng-repeat creates a child scope for each element with an $index variable indicating the position of the current element in the array. If $index is undefined I know that it's a new element (might be a better way to determine this, but it works for this example).to
is the new position of the item. I $emit a 'my-sorted' event if an existing element was moved or a 'my-created' event if a new item was added.In the controller I create the items-array and listen to the events:
As you can see, when you add or move an element the model in the scope gets updated.
These directives are not very general - you might have to do some adjustment to get them to work with your application.
You should be able to do every thing you need in your link function.