diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbeditor.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbeditor.directive.js index ca56279414..255ebf1e27 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/umbeditor.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbeditor.directive.js @@ -10,7 +10,7 @@ angular.module("umbraco.directives") scope: { view: "@", alias: "@", - config: "@", + config: "=", value: "=" }, restrict: 'E', diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js index a0c44a0222..7b34cd3761 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbproperty.directive.js @@ -7,17 +7,15 @@ angular.module("umbraco.directives") .directive('umbProperty', function (umbPropEditorHelper) { return { scope: { - alias: "@", - label: "@", - description: "@", - hidelabel: "@" + property: "=" }, transclude: true, restrict: 'E', replace: true, templateUrl: 'views/directives/umb-property.html', link: function (scope, element, attrs, ctrl) { - + } + }; }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/valpropertymsg.directive.js index ffc06eb446..aabe7a7ce4 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/valpropertymsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/valpropertymsg.directive.js @@ -8,16 +8,16 @@ * We will listen for server side validation changes * and when an error is detected for this property we'll show the error message **/ -function valPropertyMsg(serverValidationManager) { +function valPropertyMsg(serverValidationManager) { return { scope: { - currentProperty: "=property" + property: "=property" }, require: "^form", //require that this directive is contained within an ngForm replace: true, //replace the element with the template restrict: "E", //restrict to element - template: "
askjdkasj lasjd
" }, { alias: "textarea", label: "textarea", view: "textarea", value: "ajsdka sdjkds", config: { rows: 4 } }, { alias: "map", label: "Map", view: "googlemaps", value: "37.4419,-122.1419", config: { mapType: "ROADMAP", zoom: 4 } }, diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 393c7a1a67..26fe726c0e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -102,11 +102,11 @@ function contentEditingHelper($location, $routeParams, notificationsService, ser //if it contains 2 '.' then we will wire it up to a property's field if (parts.length > 2) { //add an error with a reference to the field for which the validation belongs too - serverValidationManager.addPropertyError(contentProperty, parts[2], modelState[e][0]); + serverValidationManager.addPropertyError(contentProperty.alias, parts[2], modelState[e][0]); } else { //add a generic error for the property, no reference to a specific field - serverValidationManager.addPropertyError(contentProperty, "", modelState[e][0]); + serverValidationManager.addPropertyError(contentProperty.alias, "", modelState[e][0]); } } } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/servervalidationmgr.service.js b/src/Umbraco.Web.UI.Client/src/common/services/servervalidationmgr.service.js index dac58b58e8..fa3d1e764d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/servervalidationmgr.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/servervalidationmgr.service.js @@ -28,10 +28,10 @@ function serverValidationManager($timeout) { }); } - function getPropertyErrors(self, contentProperty, fieldName) { + function getPropertyErrors(self, propertyAlias, fieldName) { //find all errors for this property return _.filter(self.items, function (item) { - return (item.propertyAlias === contentProperty.alias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); + return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); }); } @@ -88,14 +88,14 @@ function serverValidationManager($timeout) { * a particular field, otherwise we can only pinpoint that there is an error for a content property, not the * property's specific field. This is used with the val-server directive in which the directive specifies the * field alias to listen for. - * If contentProperty is null, then this subscription is for a field property (not a user defined property). + * If propertyAlias is null, then this subscription is for a field property (not a user defined property). */ - subscribe: function (contentProperty, fieldName, callback) { + subscribe: function (propertyAlias, fieldName, callback) { if (!callback) { return; } - if (contentProperty === null) { + if (propertyAlias === null) { //don't add it if it already exists var exists1 = _.find(callbacks, function (item) { return item.propertyAlias === null && item.fieldName === fieldName; @@ -104,20 +104,20 @@ function serverValidationManager($timeout) { callbacks.push({ propertyAlias: null, fieldName: fieldName, callback: callback }); } } - else if (contentProperty !== undefined) { + else if (propertyAlias !== undefined) { //don't add it if it already exists var exists2 = _.find(callbacks, function (item) { - return item.propertyAlias === contentProperty.alias && item.fieldName === fieldName; + return item.propertyAlias === propertyAlias && item.fieldName === fieldName; }); if (!exists2) { - callbacks.push({ propertyAlias: contentProperty.alias, fieldName: fieldName, callback: callback }); + callbacks.push({ propertyAlias: propertyAlias, fieldName: fieldName, callback: callback }); } } }, - unsubscribe: function(contentProperty, fieldName) { + unsubscribe: function (propertyAlias, fieldName) { - if (contentProperty === null) { + if (propertyAlias === null) { //remove all callbacks for the content field callbacks = _.reject(callbacks, function (item) { @@ -125,11 +125,11 @@ function serverValidationManager($timeout) { }); } - else if (contentProperty !== undefined) { + else if (propertyAlias !== undefined) { //remove all callbacks for the content property callbacks = _.reject(callbacks, function (item) { - return item.propertyAlias === contentProperty.alias && + return item.propertyAlias === propertyAlias && (item.fieldName === fieldName || ((item.fieldName === undefined || item.fieldName === "") && (fieldName === undefined || fieldName === ""))); }); @@ -146,14 +146,14 @@ function serverValidationManager($timeout) { * @function * * @description - * Gets all callbacks that has been registered using the subscribe method for the contentProperty + fieldName combo. + * Gets all callbacks that has been registered using the subscribe method for the propertyAlias + fieldName combo. * This will always return any callbacks registered for just the property (i.e. field name is empty) and for ones with an * explicit field name set. */ - getPropertyCallbacks: function (contentProperty, fieldName) { + getPropertyCallbacks: function (propertyAlias, fieldName) { var found = _.filter(callbacks, function (item) { //returns any callback that have been registered directly against the field and for only the property - return (item.propertyAlias === contentProperty.alias && (item.fieldName === fieldName || (item.fieldName === undefined || item.fieldName === ""))); + return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (item.fieldName === undefined || item.fieldName === ""))); }); return found; }, @@ -217,24 +217,24 @@ function serverValidationManager($timeout) { * @description * Adds an error message for the content property */ - addPropertyError: function (contentProperty, fieldName, errorMsg) { - if (!contentProperty) { + addPropertyError: function (propertyAlias, fieldName, errorMsg) { + if (!propertyAlias) { return; } //only add the item if it doesn't exist - if (!this.hasPropertyError(contentProperty, fieldName)) { + if (!this.hasPropertyError(propertyAlias, fieldName)) { this.items.push({ - propertyAlias: contentProperty.alias, + propertyAlias: propertyAlias, fieldName: fieldName, errorMsg: errorMsg }); } //find all errors for this item - var errorsForCallback = getPropertyErrors(this, contentProperty, fieldName); + var errorsForCallback = getPropertyErrors(this, propertyAlias, fieldName); //we should now call all of the call backs registered for this error - var cbs = this.getPropertyCallbacks(contentProperty, fieldName); + var cbs = this.getPropertyCallbacks(propertyAlias, fieldName); //call each callback for this error for (var cb in cbs) { executeCallback(this, errorsForCallback, cbs[cb].callback); @@ -250,14 +250,14 @@ function serverValidationManager($timeout) { * @description * Removes an error message for the content property */ - removePropertyError: function (contentProperty, fieldName) { + removePropertyError: function (propertyAlias, fieldName) { - if (!contentProperty) { + if (!propertyAlias) { return; } //remove the item this.items = _.reject(this.items, function (item) { - return (item.propertyAlias === contentProperty.alias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); + return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); }); }, @@ -302,10 +302,10 @@ function serverValidationManager($timeout) { * @description * Gets the error message for the content property */ - getPropertyError: function (contentProperty, fieldName) { + getPropertyError: function (propertyAlias, fieldName) { var err = _.find(this.items, function (item) { //return true if the property alias matches and if an empty field name is specified or the field name matches - return (item.propertyAlias === contentProperty.alias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); + return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); }); return err; }, @@ -336,10 +336,10 @@ function serverValidationManager($timeout) { * @description * Checks if the content property + field name combo has an error */ - hasPropertyError: function (contentProperty, fieldName) { + hasPropertyError: function (propertyAlias, fieldName) { var err = _.find(this.items, function (item) { //return true if the property alias matches and if an empty field name is specified or the field name matches - return (item.propertyAlias === contentProperty.alias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); + return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === ""))); }); return err ? true : false; }, diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js index ad0f47a034..5c99e75dd4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js @@ -8,13 +8,36 @@ */ function ContentEditController($scope, $routeParams, $location, contentResource, notificationsService, angularHelper, serverValidationManager, contentEditingHelper) { + /** adds the custom controls to the generic props tab above the user props */ + function configureGenericPropertiesTab(genericPropsTab, content) { + + genericPropsTab.properties.splice(0, 0, + { + label: 'Created', + description: 'Time this document was created', + value: content.createDate, + view: "readonlyvalue", + config: { filter: 'date', format: 'medium' }, + alias: "umb_createdate" //can't overlap with user defined props!! important for validation. + }, + { + label: 'Updated', + description: 'Time this document was last updated', + value: content.updateDate, + view: "readonlyvalue", + config: { filter: 'date', format: 'medium' }, + alias: "umb_updatedate" //can't overlap with user defined props!! important for validation. + }); + } + if ($routeParams.create) { //we are creating so get an empty content item contentResource.getScaffold($routeParams.id, $routeParams.doctype) .then(function(data) { $scope.contentLoaded = true; $scope.content = data; - $scope.genericPropertiesTab = $.grep($scope.content.tabs, function(e){ return e.id === 0; })[0]; + $scope.genericPropertiesTab = $.grep($scope.content.tabs, function (e) { return e.id === 0; })[0]; + configureGenericPropertiesTab($scope.genericPropertiesTab, $scope.content); }); } else { @@ -24,6 +47,7 @@ function ContentEditController($scope, $routeParams, $location, contentResource, $scope.contentLoaded = true; $scope.content = data; $scope.genericPropertiesTab = $.grep($scope.content.tabs, function(e){ return e.id === 0; })[0]; + configureGenericPropertiesTab($scope.genericPropertiesTab, $scope.content); //in one particular special case, after we've created a new item we redirect back to the edit // route but there might be server validation errors in the collection which we need to display // after the redirect, so we will bind all subscriptions which will show the server validation errors @@ -88,7 +112,7 @@ function ContentEditController($scope, $routeParams, $location, contentResource, }; - $scope.exludeLastTab = function(item) { + $scope.exludeLastTab = function(item, args) { return item.id !== 0; }; } diff --git a/src/Umbraco.Web.UI.Client/src/views/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/content/edit.html index 4b3e1b3f82..32efa8d5bb 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/edit.html @@ -1,97 +1,70 @@