Streamlines how forms (editors) work with a new formHelper, this reduces much of the repetitive code and also ensures that the correct events fire, this will be the start of streamlining how all forms work - even simple ones.
This commit is contained in:
@@ -198,21 +198,10 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser
|
||||
if (!args) {
|
||||
throw "args cannot be null";
|
||||
}
|
||||
if (!args.scope) {
|
||||
throw "args.scope cannot be null";
|
||||
}
|
||||
if (!args.scope.content) {
|
||||
throw "args.scope.content cannot be null";
|
||||
}
|
||||
if (!args.newContent) {
|
||||
throw "args.newContent cannot be null";
|
||||
}
|
||||
|
||||
for (var i = 0; i < args.newContent.notifications.length; i++) {
|
||||
notificationsService.showNotification(args.newContent.notifications[i]);
|
||||
}
|
||||
|
||||
args.scope.$broadcast("formSubmitted", { scope: args.scope });
|
||||
if (!this.redirectToCreatedContent(args.redirectId ? args.redirectId : args.newContent.id)) {
|
||||
|
||||
//we are not redirecting because this is not new content, it is existing content. In this case
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.services.formHelper
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* A utility class used to streamline how forms are developed, to ensure that validation is check and displayed consistently and to ensure that the correct events
|
||||
* fire when they need to.
|
||||
*/
|
||||
function formHelper(angularHelper, serverValidationManager, $timeout, notificationsService) {
|
||||
return {
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name umbraco.services.formHelper#submitForm
|
||||
* @methodOf umbraco.services.formHelper
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Called by controllers when submitting a form - this ensures that all client validation is checked,
|
||||
* server validation is cleared, that the correct events execute and status messages are displayed.
|
||||
* This returns true if the form is valid, otherwise false if form submission cannot continue.
|
||||
*
|
||||
* @param {object} args An object containing arguments for form submission
|
||||
*/
|
||||
submitForm: function (args) {
|
||||
|
||||
var currentForm;
|
||||
|
||||
if (!args) {
|
||||
throw "args cannot be null";
|
||||
}
|
||||
if (!args.scope) {
|
||||
throw "args.scope cannot be null";
|
||||
}
|
||||
if (!args.formCtrl) {
|
||||
//try to get the closest form controller
|
||||
currentForm = angularHelper.getRequiredCurrentForm(args.scope);
|
||||
}
|
||||
else {
|
||||
currentForm = args.formCtrl;
|
||||
}
|
||||
//if no statusPropertyName is set we'll default to formStatus.
|
||||
if (!args.statusPropertyName) {
|
||||
args.statusPropertyName = "formStatus";
|
||||
}
|
||||
//if no statusTimeout is set, we'll default to 2500 ms
|
||||
if (!args.statusTimeout) {
|
||||
args.statusTimeout = 2500;
|
||||
}
|
||||
|
||||
//the first thing any form must do is broadcast the formSubmitting event
|
||||
args.scope.$broadcast("formSubmitting", { scope: args.scope });
|
||||
|
||||
//then check if the form is valid
|
||||
if (!args.skipValidation) {
|
||||
if (currentForm.$invalid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//reset the server validations
|
||||
serverValidationManager.reset();
|
||||
|
||||
//check if a form status should be set on the scope
|
||||
if (args.statusMessage) {
|
||||
args.scope[args.statusPropertyName] = args.statusMessage;
|
||||
|
||||
//clear the message after the timeout
|
||||
$timeout(function () {
|
||||
args.scope[args.statusPropertyName] = undefined;
|
||||
}, args.statusTimeout);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name umbraco.services.formHelper#submitForm
|
||||
* @methodOf umbraco.services.formHelper
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Called by controllers when a form has been successfully submitted. the correct events execute
|
||||
* and that the notifications are displayed if there are any.
|
||||
*
|
||||
* @param {object} args An object containing arguments for form submission
|
||||
*/
|
||||
resetForm: function (args) {
|
||||
if (!args) {
|
||||
throw "args cannot be null";
|
||||
}
|
||||
if (!args.scope) {
|
||||
throw "args.scope cannot be null";
|
||||
}
|
||||
|
||||
if (angular.isArray(args.notifications)) {
|
||||
for (var i = 0; i < args.notifications.length; i++) {
|
||||
notificationsService.showNotification(args.notifications[i]);
|
||||
}
|
||||
}
|
||||
|
||||
args.scope.$broadcast("formSubmitted", { scope: args.scope });
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.services').factory('formHelper', formHelper);
|
||||
@@ -454,20 +454,6 @@ input[type="checkbox"][readonly] {
|
||||
}
|
||||
}
|
||||
|
||||
//non-html5 states, pp: added default ng-invalid class
|
||||
input.highlight-error,
|
||||
select.highlight-error,
|
||||
textarea.highlight-error,
|
||||
.ng-dirty input.ng-invalid,
|
||||
.ng-dirty select.ng-invalid,
|
||||
.ng-dirty textarea.ng-invalid{
|
||||
border-color: #953b39 !important;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
|
||||
}
|
||||
|
||||
|
||||
// FORM ACTIONS
|
||||
// ------------
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the content editor
|
||||
*/
|
||||
function ContentEditController($scope, $routeParams, $q, $timeout, $window, contentResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager) {
|
||||
function ContentEditController($scope, $routeParams, $q, $timeout, $window, contentResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper) {
|
||||
|
||||
if ($routeParams.create) {
|
||||
//we are creating so get an empty content item
|
||||
@@ -33,56 +33,55 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, cont
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: Need to figure out a way to share the saving and event broadcasting with all editors!
|
||||
|
||||
$scope.unPublish = function () {
|
||||
|
||||
$scope.setStatus("Unpublishing...");
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Unpublishing...", skipValidation: true })) {
|
||||
|
||||
contentResource.unPublish($scope.content.id)
|
||||
.then(function (data) {
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
contentResource.unPublish($scope.content.id)
|
||||
.then(function (data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.saveAndPublish = function () {
|
||||
|
||||
$scope.setStatus("Publishing...");
|
||||
$scope.$broadcast("formSubmitting", { scope: $scope });
|
||||
|
||||
var currentForm = angularHelper.getRequiredCurrentForm($scope);
|
||||
|
||||
//don't continue if the form is invalid
|
||||
if (currentForm.$invalid) return;
|
||||
$scope.saveAndPublish = function() {
|
||||
|
||||
serverValidationManager.reset();
|
||||
|
||||
contentResource.publish($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Publishing..." })) {
|
||||
|
||||
contentResource.publish($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
|
||||
}, function(err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
redirectOnFailure: true,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
|
||||
});
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
}
|
||||
|
||||
}, function (err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
redirectOnFailure: true,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.preview = function(content){
|
||||
@@ -95,48 +94,38 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, cont
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setStatus = function(status){
|
||||
//add localization
|
||||
$scope.status = status;
|
||||
$timeout(function(){
|
||||
$scope.status = undefined;
|
||||
}, 2500);
|
||||
};
|
||||
|
||||
$scope.save = function () {
|
||||
$scope.save = function() {
|
||||
var deferred = $q.defer();
|
||||
|
||||
$scope.setStatus("Saving...");
|
||||
$scope.$broadcast("formSubmitting", { scope: $scope });
|
||||
|
||||
var currentForm = angularHelper.getRequiredCurrentForm($scope);
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
|
||||
|
||||
//don't continue if the form is invalid
|
||||
if (currentForm.$invalid) return;
|
||||
contentResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
serverValidationManager.reset();
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
|
||||
contentResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
|
||||
deferred.resolve(data);
|
||||
}, function(err) {
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
allOrigProps: contentEditingHelper.getAllProps($scope.content)
|
||||
});
|
||||
|
||||
deferred.reject(err);
|
||||
});
|
||||
|
||||
navigationService.syncPath(data.path.split(","));
|
||||
|
||||
deferred.resolve(data);
|
||||
}, function (err) {
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
allOrigProps: contentEditingHelper.getAllProps($scope.content)
|
||||
});
|
||||
|
||||
deferred.reject(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
deferred.reject();
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="span8">
|
||||
<div class="btn-toolbar pull-right umb-btn-toolbar">
|
||||
<div class="btn-group" ng-animate="'fade'" ng-show="status">
|
||||
<p class="btn btn-link umb-status-label">{{status}}</p>
|
||||
<p class="btn btn-link umb-status-label">{{formStatus}}</p>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the media editor
|
||||
*/
|
||||
function mediaEditController($scope, $routeParams, mediaResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, $timeout) {
|
||||
function mediaEditController($scope, $routeParams, mediaResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper) {
|
||||
|
||||
if ($routeParams.create) {
|
||||
|
||||
@@ -32,44 +32,32 @@ function mediaEditController($scope, $routeParams, mediaResource, notificationsS
|
||||
});
|
||||
}
|
||||
|
||||
$scope.setStatus = function(status){
|
||||
//add localization
|
||||
$scope.status = status;
|
||||
$timeout(function(){
|
||||
$scope.status = undefined;
|
||||
}, 2500);
|
||||
};
|
||||
|
||||
$scope.save = function () {
|
||||
|
||||
$scope.setStatus("Saving...");
|
||||
|
||||
$scope.$broadcast("formSubmitting", { scope: $scope });
|
||||
|
||||
var currentForm = angularHelper.getRequiredCurrentForm($scope);
|
||||
//don't continue if the form is invalid
|
||||
if (currentForm.$invalid) return;
|
||||
|
||||
serverValidationManager.reset();
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
|
||||
|
||||
mediaResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
mediaResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
}, function(err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
redirectOnFailure: true,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
|
||||
});
|
||||
});
|
||||
|
||||
}, function (err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
redirectOnFailure: true,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="span8">
|
||||
<div class="btn-toolbar pull-right umb-btn-toolbar">
|
||||
<div class="btn-group" ng-animate="'fade'" ng-show="status">
|
||||
<p class="btn btn-link umb-status-label">{{status}}</p>
|
||||
<p class="btn btn-link umb-status-label">{{formStatus}}</p>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the member editor
|
||||
*/
|
||||
function MemberEditController($scope, $routeParams, $location, $q, $timeout, $window, memberResource, entityResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager) {
|
||||
function MemberEditController($scope, $routeParams, $location, $q, $window, memberResource, entityResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, formHelper) {
|
||||
|
||||
if ($routeParams.create) {
|
||||
//we are creating so get an empty member item
|
||||
@@ -45,53 +45,34 @@ function MemberEditController($scope, $routeParams, $location, $q, $timeout, $wi
|
||||
|
||||
}
|
||||
|
||||
//TODO: Need to figure out a way to share the saving and event broadcasting with all editors!
|
||||
|
||||
$scope.setStatus = function(status){
|
||||
//add localization
|
||||
$scope.status = status;
|
||||
$timeout(function(){
|
||||
$scope.status = undefined;
|
||||
}, 2500);
|
||||
};
|
||||
$scope.save = function() {
|
||||
|
||||
$scope.save = function () {
|
||||
var deferred = $q.defer();
|
||||
|
||||
$scope.setStatus("Saving...");
|
||||
$scope.$broadcast("formSubmitting", { scope: $scope });
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
|
||||
|
||||
var currentForm = angularHelper.getRequiredCurrentForm($scope);
|
||||
memberResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function(data) {
|
||||
|
||||
//don't continue if the form is invalid
|
||||
if (currentForm.$invalid) return;
|
||||
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
|
||||
|
||||
serverValidationManager.reset();
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
//specify a custom id to redirect to since we want to use the GUID
|
||||
redirectId: data.key,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
}, function (err) {
|
||||
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
allOrigProps: contentEditingHelper.getAllProps($scope.content)
|
||||
});
|
||||
|
||||
memberResource.save($scope.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
|
||||
contentEditingHelper.handleSuccessfulSave({
|
||||
scope: $scope,
|
||||
newContent: data,
|
||||
//specify a custom id to redirect to since we want to use the GUID
|
||||
redirectId: data.key,
|
||||
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
|
||||
});
|
||||
|
||||
deferred.resolve(data);
|
||||
|
||||
}, function (err) {
|
||||
contentEditingHelper.handleSaveError({
|
||||
err: err,
|
||||
allNewProps: contentEditingHelper.getAllProps(err.data),
|
||||
allOrigProps: contentEditingHelper.getAllProps($scope.content)
|
||||
});
|
||||
|
||||
deferred.reject(err);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user