Fixes action dialog so that it doesn't keep appending content to the container each time you move to a diff tree node and click create. Before there was nothing removing the previous $modal object from the container so you'd end up with the same create action dialog being shown for each node and then it would eventually show a munged up duplicated markup and jquery would throw a stack overflow exception.
This commit is contained in:
@@ -30,15 +30,18 @@
|
||||
angular.module('umbraco.services')
|
||||
.factory('dialogService', ['$rootScope', '$compile', '$http', '$timeout', '$q', '$templateCache',
|
||||
function ($rootScope, $compile, $http, $timeout, $q, $templateCache) {
|
||||
var _dialogs = [];
|
||||
|
||||
var dialogs = [];
|
||||
|
||||
$rootScope.$on("closeDialogs", function () {
|
||||
for (var i = 0; i < _dialogs.length; i++) {
|
||||
var dialog = _dialogs[i];
|
||||
for (var i = 0; i < dialogs.length; i++) {
|
||||
var dialog = dialogs[i];
|
||||
removeDialog(dialog);
|
||||
_dialogs.splice(i, 1);
|
||||
dialogs.splice(i, 1);
|
||||
}
|
||||
});
|
||||
|
||||
/** Internal method that handles closing a specific dialog */
|
||||
function removeDialog(dialog) {
|
||||
dialog.modal("hide");
|
||||
|
||||
@@ -48,8 +51,8 @@ angular.module('umbraco.services')
|
||||
}, 250);
|
||||
}
|
||||
|
||||
//internal method that handles opening all dialogs
|
||||
function _open(options) {
|
||||
/** Internal method that handles opening all dialogs */
|
||||
function openDialog(options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
@@ -58,7 +61,7 @@ angular.module('umbraco.services')
|
||||
container = options.container || $("body"),
|
||||
animationClass = options.animation || "fade",
|
||||
modalClass = options.modalClass || "umb-modal",
|
||||
width = options.width || "100%";
|
||||
width = options.width || "100%",
|
||||
templateUrl = options.template || "views/common/notfound.html";
|
||||
|
||||
//if a callback is available
|
||||
@@ -84,7 +87,7 @@ angular.module('umbraco.services')
|
||||
.addClass(modalClass);
|
||||
|
||||
//push the modal into the global modal collection
|
||||
_dialogs.push($modal);
|
||||
dialogs.push($modal);
|
||||
|
||||
//if iframe is enabled, inject that instead of a template
|
||||
if (options.iframe) {
|
||||
@@ -99,9 +102,7 @@ angular.module('umbraco.services')
|
||||
$compile($modal)(scope);
|
||||
});
|
||||
|
||||
if (width) {
|
||||
$modal.css("width", width);
|
||||
}
|
||||
$modal.css("width", width);
|
||||
|
||||
//Autoshow
|
||||
if (options.show) {
|
||||
@@ -109,82 +110,89 @@ angular.module('umbraco.services')
|
||||
}
|
||||
|
||||
return $modal;
|
||||
} else {
|
||||
return $q.when($templateCache.get(templateUrl) || $http.get(templateUrl, { cache: true }).then(function (res) { return res.data; }))
|
||||
.then(function onSuccess(template) {
|
||||
}
|
||||
else {
|
||||
|
||||
//We need to load the template with an httpget and once it's loaded we'll compile and assign the result to the container
|
||||
// object. However since the result could be a promise or just data we need to use a $q.when. We still need to return the
|
||||
// $modal object so we'll actually return the modal object synchronously without waiting for the promise. Otherwise this openDialog
|
||||
// method will always need to return a promise which gets nasty because of promises in promises plus the result just needs a reference
|
||||
// to the $modal object which will not change (only it's contents will change).
|
||||
$q.when($templateCache.get(templateUrl) || $http.get(templateUrl, { cache: true }).then(function(res) { return res.data; }))
|
||||
.then(function onSuccess(template) {
|
||||
|
||||
// Build modal object
|
||||
$modal
|
||||
.html(template);
|
||||
// Build modal object
|
||||
$modal.html(template);
|
||||
|
||||
//append to body or other container element
|
||||
container.append($modal);
|
||||
//append to body or other container element
|
||||
container.append($modal);
|
||||
|
||||
// Compile modal content
|
||||
$timeout(function () {
|
||||
$compile($modal)(scope);
|
||||
});
|
||||
// Compile modal content
|
||||
$timeout(function() {
|
||||
$compile($modal)(scope);
|
||||
});
|
||||
|
||||
//Scope to handle data from the modal form
|
||||
scope.dialogData = {};
|
||||
scope.dialogData.selection = [];
|
||||
//Scope to handle data from the modal form
|
||||
scope.dialogData = {};
|
||||
scope.dialogData.selection = [];
|
||||
|
||||
// Provide scope display functions
|
||||
//this passes the modal to the current scope
|
||||
scope.$modal = function (name) {
|
||||
$modal.modal(name);
|
||||
};
|
||||
// Provide scope display functions
|
||||
//this passes the modal to the current scope
|
||||
scope.$modal = function(name) {
|
||||
$modal.modal(name);
|
||||
};
|
||||
|
||||
scope.hide = function () {
|
||||
$modal.modal('hide');
|
||||
scope.hide = function() {
|
||||
$modal.modal('hide');
|
||||
|
||||
$modal.remove();
|
||||
$("#" + $modal.attr("id")).remove();
|
||||
};
|
||||
$modal.remove();
|
||||
$("#" + $modal.attr("id")).remove();
|
||||
};
|
||||
|
||||
scope.show = function () {
|
||||
$modal.modal('show');
|
||||
};
|
||||
scope.show = function() {
|
||||
$modal.modal('show');
|
||||
};
|
||||
|
||||
scope.submit = function (data) {
|
||||
if (callback) {
|
||||
callback(data);
|
||||
}
|
||||
|
||||
$modal.modal('hide');
|
||||
|
||||
$modal.remove();
|
||||
$("#" + $modal.attr("id")).remove();
|
||||
};
|
||||
|
||||
scope.select = function (item) {
|
||||
if (scope.dialogData.selection.indexOf(item) < 0) {
|
||||
scope.dialogData.selection.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
scope.dismiss = scope.hide;
|
||||
|
||||
// Emit modal events
|
||||
angular.forEach(['show', 'shown', 'hide', 'hidden'], function (name) {
|
||||
$modal.on(name, function (ev) {
|
||||
scope.$emit('modal-' + name, ev);
|
||||
});
|
||||
});
|
||||
|
||||
// Support autofocus attribute
|
||||
$modal.on('shown', function (event) {
|
||||
$('input[autofocus]', $modal).first().trigger('focus');
|
||||
});
|
||||
|
||||
//Autoshow
|
||||
if (options.show) {
|
||||
$modal.modal('show');
|
||||
scope.submit = function(data) {
|
||||
if (callback) {
|
||||
callback(data);
|
||||
}
|
||||
|
||||
//Return the modal object
|
||||
return $modal;
|
||||
$modal.modal('hide');
|
||||
|
||||
$modal.remove();
|
||||
$("#" + $modal.attr("id")).remove();
|
||||
};
|
||||
|
||||
scope.select = function(item) {
|
||||
if (scope.dialogData.selection.indexOf(item) < 0) {
|
||||
scope.dialogData.selection.push(item);
|
||||
}
|
||||
};
|
||||
|
||||
scope.dismiss = scope.hide;
|
||||
|
||||
// Emit modal events
|
||||
angular.forEach(['show', 'shown', 'hide', 'hidden'], function(name) {
|
||||
$modal.on(name, function(ev) {
|
||||
scope.$emit('modal-' + name, ev);
|
||||
});
|
||||
});
|
||||
|
||||
// Support autofocus attribute
|
||||
$modal.on('shown', function(event) {
|
||||
$('input[autofocus]', $modal).first().trigger('focus');
|
||||
});
|
||||
|
||||
//Autoshow
|
||||
if (options.show) {
|
||||
$modal.modal('show');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//Return the modal object outside of the promise!
|
||||
return $modal;
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +205,8 @@ angular.module('umbraco.services')
|
||||
* @methodOf umbraco.services.dialogService
|
||||
*
|
||||
* @description
|
||||
* Opens a modal rendering a given template url
|
||||
* Opens a modal rendering a given template url.
|
||||
*
|
||||
* @param {Object} options rendering options
|
||||
* @param {DomElement} options.container the DOM element to inject the modal into, by default set to body
|
||||
* @param {Function} options.callback function called when the modal is submitted
|
||||
@@ -208,10 +217,24 @@ angular.module('umbraco.services')
|
||||
* @param {Int} options.width set a width on the modal, only needed for iframes
|
||||
*/
|
||||
open: function (options) {
|
||||
return _open(options);
|
||||
return openDialog(options);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.dialogService#close
|
||||
* @methodOf umbraco.services.dialogService
|
||||
*
|
||||
* @description
|
||||
* Closes a specific dialog
|
||||
* @param {Object} dialog the dialog object to close
|
||||
*/
|
||||
close: function(dialog) {
|
||||
removeDialog(dialog);
|
||||
},
|
||||
|
||||
mediaPicker: function (options) {
|
||||
return _open({
|
||||
return openDialog({
|
||||
scope: options.scope,
|
||||
callback: options.callback,
|
||||
template: 'views/common/dialogs/mediaPicker.html',
|
||||
@@ -219,7 +242,7 @@ angular.module('umbraco.services')
|
||||
});
|
||||
},
|
||||
contentPicker: function (options) {
|
||||
return _open({
|
||||
return openDialog({
|
||||
scope: options.scope,
|
||||
callback: options.callback,
|
||||
template: 'views/common/dialogs/contentPicker.html',
|
||||
@@ -227,7 +250,7 @@ angular.module('umbraco.services')
|
||||
});
|
||||
},
|
||||
macroPicker: function (options) {
|
||||
return _open({
|
||||
return openDialog({
|
||||
scope: options.scope,
|
||||
callback: options.callback,
|
||||
template: 'views/common/dialogs/macroPicker.html',
|
||||
@@ -235,7 +258,7 @@ angular.module('umbraco.services')
|
||||
});
|
||||
},
|
||||
propertyDialog: function (options) {
|
||||
return _open({
|
||||
return openDialog({
|
||||
scope: options.scope,
|
||||
callback: options.callback,
|
||||
template: 'views/common/dialogs/property.html',
|
||||
@@ -246,7 +269,7 @@ angular.module('umbraco.services')
|
||||
//deprecated
|
||||
append: function (options) {
|
||||
|
||||
return _open(options);
|
||||
return openDialog(options);
|
||||
|
||||
/*
|
||||
var scope = options.scope || $rootScope.$new(),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
angular.module('umbraco.services')
|
||||
.factory('navigationService', function ($rootScope, $routeParams, $log, $location, dialogService, treeService, sectionResource) {
|
||||
.factory('navigationService', function ($rootScope, $routeParams, $log, $location, $q, dialogService, treeService, sectionResource) {
|
||||
|
||||
var currentSection = $routeParams.section;
|
||||
var currentId = $routeParams.id;
|
||||
@@ -203,7 +203,7 @@ angular.module('umbraco.services')
|
||||
* template is located in views/common/dialogs/user.html
|
||||
*/
|
||||
showUserDialog: function () {
|
||||
var d = dialogService.open(
|
||||
return dialogService.open(
|
||||
{
|
||||
template: "views/common/dialogs/user.html",
|
||||
modalClass: "umb-modal-left",
|
||||
@@ -243,15 +243,15 @@ angular.module('umbraco.services')
|
||||
iframe = true;
|
||||
}
|
||||
|
||||
var d = dialogService.open(
|
||||
{
|
||||
container: $("#dialog div.umb-panel-body"),
|
||||
scope: scope,
|
||||
inline: true,
|
||||
show: true,
|
||||
iframe: iframe,
|
||||
template: templateUrl
|
||||
});
|
||||
return dialogService.open(
|
||||
{
|
||||
container: $("#dialog div.umb-panel-body"),
|
||||
scope: scope,
|
||||
inline: true,
|
||||
show: true,
|
||||
iframe: iframe,
|
||||
template: templateUrl
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
*
|
||||
* @param {navigationService} navigationService A reference to the navigationService
|
||||
*/
|
||||
function NavigationController($scope,$rootScope, $location, navigationService, historyService, sectionResource) {
|
||||
function NavigationController($scope,$rootScope, $location, navigationService, dialogService, historyService, sectionResource) {
|
||||
|
||||
var actionDialog = null;
|
||||
|
||||
//load navigation service handlers
|
||||
$scope.changeSection = navigationService.changeSection;
|
||||
$scope.showTree = navigationService.showTree;
|
||||
@@ -90,7 +93,13 @@ function NavigationController($scope,$rootScope, $location, navigationService, h
|
||||
});
|
||||
|
||||
$scope.openDialog = function (currentNode, action, currentSection) {
|
||||
navigationService.showDialog({
|
||||
|
||||
//ensure the actionDialog is cleared before opening another!
|
||||
if (actionDialog) {
|
||||
dialogService.close(actionDialog);
|
||||
}
|
||||
|
||||
actionDialog = navigationService.showDialog({
|
||||
scope: $scope,
|
||||
node: currentNode,
|
||||
action: action,
|
||||
|
||||
Reference in New Issue
Block a user