Reputation: 1034
I've an ng-repeat in my angular template which needs to be sortable. I'm using jQuery-ui's Sortable to implement it.
The JS:
$scope.data = [{"key":123,"val":"a"},
{"key":124,"val":"b"},
{"key":125,"val":"c"}];
$(".sortable").sortable();
The template:
<div class="sortable">
<div ng-repeat="sub in data" >
{{sub.key}}
</div>
</div>
This works perfectly fine, and I can drag and drop the elements. However, when a ng-repeat is nested within another, it doesn't work; I'm unable to drag anything. On using Chrome inspector, I see that the class 'ui-sortable' is not added to any element at all.
The JS:
$scope.subJson = [{"name":"MS1","slides":[{"title":"Title1"},{"title":"Title2"}]},{"name":"MS2","slides":[{"title":"Title3"},{"title":"Title4"}]}];
$(".sortable").sortable();
The template:
<div>
<div ng-repeat="sub in subJson" >
{{sub.name}}
<div class="sortable">
<div ng-repeat="slide in sub.slides" >
{{slide.title}}
</div>
</div>
</div>
</div>
Why does this happen? Is there a solution?
Upvotes: 3
Views: 4207
Reputation: 1957
Sortable
needs to reload the object to control.
Put the $(".sortable").sortable()
; inside a function and then call that function in the item row of the list.
For example:
function init() {
$(".sortable").sortable();
}
then in your html:
<div>
<div ng-repeat="sub in subJson" >
{{sub.name}}
<div class="sortable">
<div ng-repeat="slide in sub.slides" >
<div class="layer-draggable"
ng-mousedown="init()">
{{slide.title}}
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 6315
Maybe this problem lies in the execution time of $('.sortable').sortable()
.
Sortable finds elements with classname sortable
immediately after the controller is set up.
At that time the ng-repeat
has not been initiated, so the $('.sortable')
finds no element.
In the js fiddle below, the output in console shows this problem.
http://jsfiddle.net/Q5FWt/439/
A quick dirty fix is put $('.sortable').sortable()
in a setTimeout
.
However, manipulating dom element is never an angular way!
A desirable way to achieve this is to construct a directive, or use a angular-ui plugin like this, https://github.com/angular-ui/ui-sortable
Upvotes: 2