diff --git a/app/controllers/controller.js b/app/controllers/controller.js index f5b05d3..50dc297 100644 --- a/app/controllers/controller.js +++ b/app/controllers/controller.js @@ -52,6 +52,34 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc cursor: "move", handle: ".handle", tolerance: "pointer", + activate: function(ev, ui) { + + // Variables. + var parentItem = ui.item.parent(); + var thisElement = parentItem[0]; + var targetElement = ev.target; + var targetItem = angular.element(targetElement); + + // The source of the drag can always be dropped back onto. + if (targetElement === thisElement) { + return; + } + + // Variables. + var sourceScope = ui.item.scope(); + var targetScope = targetItem.scope(); + var valid = canMove(sourceScope, targetScope); + + // If the sortable can't be moved to the target Archetype, disable + // the target Archetype's sortable temporarily. + if (!valid) { + var targetSortable = targetItem.sortable("instance"); + targetSortable.disable(); + parentItem.sortable("refresh"); + archetypeService.rememberDisabledSortable(targetSortable); + } + + }, start: function(ev, ui) { archetypeService.storeEditors(ui.item.parent()); $scope.$apply(function() { @@ -73,12 +101,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc if (sourceScope && !sameScope) { // Variables. - var targetFieldsets = targetScope.model.config.fieldsets; - var model = sourceScope.fieldsetConfigModel; - var canRemove = sourceScope.canRemove(); - var canAdd = targetScope.canAdd(); - var valid = canRemove && canAdd; - valid = valid && modelMatchesAnyFieldset(model, targetFieldsets); + var valid = canMove(sourceScope, targetScope); // If update isn't allowed, cancel the drag operation. if (!valid) { @@ -119,13 +142,21 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc }, stop: function (ev, ui) { + + // Done sorting. draggedParent.scope().doingSort = false; + + // Enable disabled sortables. + archetypeService.enableSortables(); + + // Restore rich text editors. var parent = null; var target = ui.item.sortable.droptarget; if (target) { parent = target.parent(); } archetypeService.restoreEditors(parent); + } }; @@ -145,7 +176,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc // Enable cross-archetype dragging? if ($scope.model.config.enableCrossDragging) { - $scope.sortableOptions.connectWith = ".archetypeSortable"; + $scope.sortableOptions.connectWith = ".archetypeSortable:not(.invalid)"; } // Checks if the specified model's properties match all of the properties in any of @@ -790,4 +821,17 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc }, fieldsets); } + // Indicates whether or not the fieldset can be moved between the source and target scope. + // The source scope is the scope of the fieldset being dragged. + // The target scope is the scope of the Archetype to drop into. + function canMove(sourceScope, targetScope) { + var targetFieldsets = targetScope.model.config.fieldsets; + var model = sourceScope.fieldsetConfigModel; + var canRemove = sourceScope.canRemove(); + var canAdd = targetScope.canAdd(); + var valid = canRemove && canAdd; + valid = valid && modelMatchesAnyFieldset(model, targetFieldsets); + return valid; + } + }); diff --git a/app/services/archetypeService.js b/app/services/archetypeService.js index 7dba1a6..a4379e4 100644 --- a/app/services/archetypeService.js +++ b/app/services/archetypeService.js @@ -4,6 +4,7 @@ angular.module('umbraco.services').factory('archetypeService', function () { var draggedRteArchetype; var rteClass = ".umb-rte textarea"; var editorSettings = {}; + var disabledSortables = []; //public return { @@ -199,6 +200,17 @@ angular.module('umbraco.services').factory('archetypeService', function () { if (!editorState.temporaryId || regenerateId) { editorState.temporaryId = _.uniqueId("property-temp-id-"); } + }, + // Remembers a sortable that has been disabled (so it can be enabled later). + rememberDisabledSortable: function(sortable) { + disabledSortables.push(sortable); + }, + // Enables all of the sortables that were disabled. + enableSortables: function() { + _.each(disabledSortables, function(sortable) { + sortable.enable(); + }); + disabledSortables = []; } } }); \ No newline at end of file