Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Commit 521fcc3

Browse files
Jeremy Mickelsondouglasduteil
Jeremy Mickelson
authored andcommitted
Use a different strategy for working with Angular that works with Angular 1.2 ng-repeat comments. #48
1 parent 3d9a21e commit 521fcc3

File tree

1 file changed

+37
-66
lines changed

1 file changed

+37
-66
lines changed

src/sortable.js

+37-66
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
angular.module('ui.sortable', [])
77
.value('uiSortableConfig',{})
88
.directive('uiSortable', [
9-
'uiSortableConfig', '$log',
10-
function(uiSortableConfig, log) {
9+
'uiSortableConfig', '$timeout', '$log',
10+
function(uiSortableConfig, $timeout, $log) {
1111
return {
1212
require: '?ngModel',
1313
link: function(scope, element, attrs, ngModel) {
14+
var savedNodes;
1415

1516
function combineCallbacks(first,second){
1617
if( second && (typeof second === "function") ){
@@ -32,87 +33,57 @@ angular.module('ui.sortable', [])
3233
update:null
3334
};
3435

35-
var apply = function(e, ui) {
36-
if (ui.item.sortable.resort || ui.item.sortable.relocate) {
37-
scope.$apply();
38-
}
39-
};
40-
4136
angular.extend(opts, uiSortableConfig);
4237

4338
if (ngModel) {
4439

45-
ngModel.$render = function() {
46-
element.sortable( "refresh" );
47-
};
40+
// When we add or remove elements, we need the sortable to 'refresh'
41+
scope.$watch(attrs.ngModel+'.length', function() {
42+
// Timeout to let ng-repeat modify the DOM
43+
$timeout(function() {
44+
element.sortable( "refresh" );
45+
});
46+
});
4847

4948
callbacks.start = function(e, ui) {
5049
// Save position of dragged item
5150
ui.item.sortable = { index: ui.item.index() };
52-
};
53-
54-
callbacks.update = function(e, ui) {
55-
// For some reason the reference to ngModel in stop() is wrong
56-
ui.item.sortable.resort = ngModel;
57-
};
58-
59-
callbacks.receive = function(e, ui) {
60-
ui.item.sortable.relocate = true;
61-
// added item to array into correct position and set up flag
62-
ngModel.$modelValue.splice(ui.item.index(), 0, ui.item.sortable.moved);
63-
};
6451

65-
callbacks.remove = function(e, ui) {
66-
// copy data into item
67-
if (ngModel.$modelValue.length === 1) {
68-
ui.item.sortable.moved = ngModel.$modelValue.splice(0, 1)[0];
69-
} else {
70-
ui.item.sortable.moved = ngModel.$modelValue.splice(ui.item.sortable.index, 1)[0];
71-
}
52+
// We need to make a copy of the current element's contents so
53+
// we can restore it after sortable has messed it up
54+
savedNodes = element.contents().not(
55+
//Don't inlcude the placeholder
56+
element.find('.ui-sortable-placeholder'));
7257
};
7358

74-
callbacks.stop = function(e, ui) {
75-
// digest all prepared changes
76-
if (ui.item.sortable.resort && !ui.item.sortable.relocate) {
77-
78-
// Fetch saved and current position of dropped element
79-
var end, start;
80-
start = ui.item.sortable.index;
81-
end = ui.item.index();
82-
83-
// Reorder array and apply change to scope
84-
ui.item.sortable.resort.$modelValue.splice(end, 0, ui.item.sortable.resort.$modelValue.splice(start, 1)[0]);
85-
86-
}
87-
};
88-
89-
scope.$watch(attrs.uiSortable, function(newVal, oldVal){
90-
angular.forEach(newVal, function(value, key){
91-
92-
if( callbacks[key] ){
93-
// wrap the callback
94-
value = combineCallbacks( callbacks[key], value );
95-
96-
if ( key === 'stop' ){
97-
// call apply after stop
98-
value = combineCallbacks( value, apply );
99-
}
100-
}
101-
102-
element.sortable('option', key, value);
59+
callbacks.update = function(e, ui) {
60+
// Fetch saved and current position of dropped element
61+
var end, start;
62+
start = ui.item.sortable.index;
63+
end = ui.item.index();
64+
65+
// Cancel the sort (let ng-repeat do the sort for us)
66+
element.sortable('cancel');
67+
68+
// Put the nodes back exactly the way they started (this is very
69+
// important because ng-repeat uses comment elements to delineate
70+
// the start and stop of repeat sections and sortable doesn't
71+
// respect their order (even if we cancel, the order of the
72+
// comments are still messed up).
73+
savedNodes.detach().appendTo(element);
74+
75+
// Reorder array and apply change to scope
76+
scope.$apply(function() {
77+
ngModel.$modelValue.splice(end, 0, ngModel.$modelValue.splice(start, 1)[0]);
10378
});
104-
}, true);
105-
106-
angular.forEach(callbacks, function(value, key ){
79+
};
10780

81+
angular.forEach(callbacks, function(value, key){
10882
opts[key] = combineCallbacks(value, opts[key]);
10983
});
11084

111-
// call apply after stop
112-
opts.stop = combineCallbacks( opts.stop, apply );
113-
11485
} else {
115-
log.info('ui.sortable: ngModel not provided!', element);
86+
$log.info('ui.sortable: ngModel not provided!', element);
11687
}
11788

11889
// Create sortable

0 commit comments

Comments
 (0)