6
6
angular . module ( 'ui.sortable' , [ ] )
7
7
. value ( 'uiSortableConfig' , { } )
8
8
. directive ( 'uiSortable' , [
9
- 'uiSortableConfig' , '$log' ,
10
- function ( uiSortableConfig , log ) {
9
+ 'uiSortableConfig' , '$timeout' , '$ log',
10
+ function ( uiSortableConfig , $timeout , $ log) {
11
11
return {
12
12
require : '?ngModel' ,
13
13
link : function ( scope , element , attrs , ngModel ) {
14
+ var savedNodes ;
14
15
15
16
function combineCallbacks ( first , second ) {
16
17
if ( second && ( typeof second === "function" ) ) {
@@ -32,87 +33,57 @@ angular.module('ui.sortable', [])
32
33
update :null
33
34
} ;
34
35
35
- var apply = function ( e , ui ) {
36
- if ( ui . item . sortable . resort || ui . item . sortable . relocate ) {
37
- scope . $apply ( ) ;
38
- }
39
- } ;
40
-
41
36
angular . extend ( opts , uiSortableConfig ) ;
42
37
43
38
if ( ngModel ) {
44
39
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
+ } ) ;
48
47
49
48
callbacks . start = function ( e , ui ) {
50
49
// Save position of dragged item
51
50
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
- } ;
64
51
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' ) ) ;
72
57
} ;
73
58
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 ] ) ;
103
78
} ) ;
104
- } , true ) ;
105
-
106
- angular . forEach ( callbacks , function ( value , key ) {
79
+ } ;
107
80
81
+ angular . forEach ( callbacks , function ( value , key ) {
108
82
opts [ key ] = combineCallbacks ( value , opts [ key ] ) ;
109
83
} ) ;
110
84
111
- // call apply after stop
112
- opts . stop = combineCallbacks ( opts . stop , apply ) ;
113
-
114
85
} else {
115
- log . info ( 'ui.sortable: ngModel not provided!' , element ) ;
86
+ $ log. info ( 'ui.sortable: ngModel not provided!' , element ) ;
116
87
}
117
88
118
89
// Create sortable
0 commit comments