diff --git a/src/sortable.js b/src/sortable.js index 400ee15..85f1f74 100644 --- a/src/sortable.js +++ b/src/sortable.js @@ -11,8 +11,8 @@ angular.module('ui.sortable', []) return { require: '?ngModel', scope: { - ngModel: '=ngModel', - uiSortable: '=uiSortable' + ngModel: '=', + uiSortable: '=' }, link: function(scope, element, attrs, ngModel) { var savedNodes; @@ -47,6 +47,18 @@ angular.module('ui.sortable', []) return (/left|right/).test(item.css('float')) || (/inline|table-cell/).test(item.css('display')); } + function getElementScope(elementScopes, element) { + var result = null; + for (var i = 0; i < elementScopes.length; i++) { + var x = elementScopes[i]; + if (x.element[0] === element[0]) { + result = x.scope; + break; + } + } + return result; + } + function afterStop(e, ui) { ui.item.sortable._destroy(); } @@ -126,7 +138,7 @@ angular.module('ui.sortable', []) }; }; - callbacks.activate = function(/*e, ui*/) { + callbacks.activate = function(e, ui) { // We need to make a copy of the current element's contents so // we can restore it after sortable has messed it up. // This is inside activate (instead of start) in order to save @@ -151,10 +163,20 @@ angular.module('ui.sortable', []) // exact match with the placeholder's class attribute to handle // the case that multiple connected sortables exist and // the placehoilder option equals the class of sortable items - var excludes = element.find('[class="' + phElement.attr('class') + '"]'); + var excludes = element.find('[class="' + phElement.attr('class') + '"]:not([ng-repeat], [data-ng-repeat])'); savedNodes = savedNodes.not(excludes); } + + // save the directive's scope so that it is accessible from ui.item.sortable + var connectedSortables = ui.item.sortable._connectedSortables || []; + + connectedSortables.push({ + element: element, + scope: scope + }); + + ui.item.sortable._connectedSortables = connectedSortables; }; callbacks.update = function(e, ui) { @@ -165,8 +187,9 @@ angular.module('ui.sortable', []) ui.item.sortable.dropindex = ui.item.index(); var droptarget = ui.item.parent(); ui.item.sortable.droptarget = droptarget; - var attr = droptarget.attr('ng-model') || droptarget.attr('data-ng-model'); - ui.item.sortable.droptargetModel = droptarget.scope().$eval(attr); + + var droptargetScope = getElementScope(ui.item.sortable._connectedSortables, droptarget); + ui.item.sortable.droptargetModel = droptargetScope.ngModel; // Cancel the sort (let ng-repeat do the sort for us) // Don't cancel if this is the received list because it has diff --git a/test/sortable.e2e.callbacks.spec.js b/test/sortable.e2e.callbacks.spec.js index 50b182b..ae4ceb5 100644 --- a/test/sortable.e2e.callbacks.spec.js +++ b/test/sortable.e2e.callbacks.spec.js @@ -2,6 +2,12 @@ describe('uiSortable', function() { + beforeEach(module(function($compileProvider) { + if (typeof $compileProvider.debugInfoEnabled === 'function') { + $compileProvider.debugInfoEnabled(false); + } + })); + // Ensure the sortable angular module is loaded beforeEach(module('ui.sortable')); beforeEach(module('ui.sortable.testHelper')); @@ -35,7 +41,7 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { update: function(e, ui) { - if (ui.item.scope().item === 'Two') { + if (ui.item.sortable.model === 'Two') { ui.item.sortable.cancel(); } } @@ -77,7 +83,7 @@ describe('uiSortable', function() { return item; }, update: function(e, ui) { - if (ui.item.scope().item === 'Two') { + if (ui.item.sortable.model === 'Two') { ui.item.sortable.cancel(); } } @@ -117,7 +123,7 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { update: function(e, ui) { - $rootScope.logs.push('Moved element ' + ui.item.scope().item); + $rootScope.logs.push('Moved element ' + ui.item.sortable.model); } }; $rootScope.items = ['One', 'Two', 'Three']; @@ -148,7 +154,7 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { stop: function(e, ui) { - $rootScope.logs.push('Moved element ' + ui.item.scope().item); + $rootScope.logs.push('Moved element ' + ui.item.sortable.model); } }; $rootScope.items = ['One', 'Two', 'Three']; @@ -199,7 +205,7 @@ describe('uiSortable', function() { $rootScope.$apply(function() { $rootScope.opts = { update: function(e, ui) { - if (ui.item.scope().item === 'Two') { + if (ui.item.sortable.model === 'Two') { ui.item.sortable.cancel(); } updateCallbackExpectations(ui.item.sortable); @@ -276,7 +282,7 @@ describe('uiSortable', function() { uiItemSortable_Destroy = ui.item.sortable._destroy; }, update: function(e, ui) { - if (ui.item.scope().item === 'Two') { + if (ui.item.sortable.model === 'Two') { ui.item.sortable.cancel(); } } diff --git a/test/sortable.e2e.directiveoptions.spec.js b/test/sortable.e2e.directiveoptions.spec.js index bd2461c..9eba4b8 100644 --- a/test/sortable.e2e.directiveoptions.spec.js +++ b/test/sortable.e2e.directiveoptions.spec.js @@ -2,6 +2,12 @@ describe('uiSortable', function() { + beforeEach(module(function($compileProvider) { + if (typeof $compileProvider.debugInfoEnabled === 'function') { + $compileProvider.debugInfoEnabled(false); + } + })); + // Ensure the sortable angular module is loaded beforeEach(module('ui.sortable')); beforeEach(module('ui.sortable.testHelper')); diff --git a/test/sortable.e2e.directives.spec.js b/test/sortable.e2e.directives.spec.js index 1c071a4..3292944 100644 --- a/test/sortable.e2e.directives.spec.js +++ b/test/sortable.e2e.directives.spec.js @@ -2,6 +2,12 @@ describe('uiSortable', function() { + beforeEach(module(function($compileProvider) { + if (typeof $compileProvider.debugInfoEnabled === 'function') { + $compileProvider.debugInfoEnabled(false); + } + })); + // Ensure the sortable angular module is loaded beforeEach(module('ui.sortable')); beforeEach(module('ui.sortable.testHelper')); diff --git a/test/sortable.e2e.multi.spec.js b/test/sortable.e2e.multi.spec.js index efaed48..bf2c0e0 100644 --- a/test/sortable.e2e.multi.spec.js +++ b/test/sortable.e2e.multi.spec.js @@ -2,6 +2,12 @@ describe('uiSortable', function() { + beforeEach(module(function($compileProvider) { + if (typeof $compileProvider.debugInfoEnabled === 'function') { + $compileProvider.debugInfoEnabled(false); + } + })); + // Ensure the sortable angular module is loaded beforeEach(module('ui.sortable')); beforeEach(module('ui.sortable.testHelper')); @@ -68,14 +74,17 @@ describe('uiSortable', function() { inject(function($compile, $rootScope) { var elementTop, elementBottom, wrapperTop, wrapperBottom, + wrapperTopScope, wrapperBottomScope, itemsTop, itemsBottom; - wrapperTop = $compile('