diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs
index 0727c0d24f..e405fa3a3e 100644
--- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs
+++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs
@@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
+using Umbraco.Core.Composing;
using Umbraco.Core.Exceptions;
+using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.Validators
{
@@ -11,6 +13,7 @@ namespace Umbraco.Core.PropertyEditors.Validators
///
internal sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator
{
+ private readonly ILocalizedTextService _textService;
private string _regex;
///
@@ -22,8 +25,8 @@ namespace Umbraco.Core.PropertyEditors.Validators
/// Use this constructor when the validator is used as an ,
/// and the regular expression is supplied at validation time. This constructor is also used when
/// the validator is used as an and the regular expression
- /// is supplied via the method.
- public RegexValidator()
+ /// is supplied via the method.
+ public RegexValidator() : this(Current.Services.TextService, null)
{ }
///
@@ -31,10 +34,9 @@ namespace Umbraco.Core.PropertyEditors.Validators
///
/// Use this constructor when the validator is used as an ,
/// and the regular expression must be supplied when the validator is created.
- public RegexValidator(string regex)
+ public RegexValidator(ILocalizedTextService textService, string regex)
{
- if (string.IsNullOrWhiteSpace(regex))
- throw new ArgumentNullOrEmptyException(nameof(regex));
+ _textService = textService;
_regex = regex;
}
@@ -66,7 +68,7 @@ namespace Umbraco.Core.PropertyEditors.Validators
{
if (string.IsNullOrWhiteSpace(format)) throw new ArgumentNullOrEmptyException(nameof(format));
if (value == null || !new Regex(format).IsMatch(value.ToString()))
- yield return new ValidationResult("Value is invalid, it does not match the correct pattern", new[] { "value" });
+ yield return new ValidationResult(_textService.Localize("validation", "invalidPattern"), new[] { "value" });
}
}
}
diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
index bc3cf66caa..4db0afd359 100644
--- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
+++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using Umbraco.Core.Services;
namespace Umbraco.Core.PropertyEditors.Validators
{
@@ -8,6 +9,17 @@ namespace Umbraco.Core.PropertyEditors.Validators
///
internal sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator
{
+ private readonly ILocalizedTextService _textService;
+
+ public RequiredValidator()
+ {
+ }
+
+ public RequiredValidator(ILocalizedTextService textService)
+ {
+ _textService = textService;
+ }
+
///
public string ValidationName => "Required";
@@ -22,20 +34,20 @@ namespace Umbraco.Core.PropertyEditors.Validators
{
if (value == null)
{
- yield return new ValidationResult("Value cannot be null", new[] {"value"});
+ yield return new ValidationResult(_textService.Localize("validation", "invalidNull"), new[] {"value"});
yield break;
}
if (valueType.InvariantEquals(ValueTypes.Json))
{
if (value.ToString().DetectIsEmptyJson())
- yield return new ValidationResult("Value cannot be empty", new[] { "value" });
+ yield return new ValidationResult(_textService.Localize("validation", "invalidEmpty"), new[] { "value" });
yield break;
}
if (value.ToString().IsNullOrWhiteSpace())
{
- yield return new ValidationResult("Value cannot be empty", new[] { "value" });
+ yield return new ValidationResult(_textService.Localize("validation", "invalidEmpty"), new[] { "value" });
}
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/tabbedcontent.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/tabbedcontent.directive.js
new file mode 100644
index 0000000000..ba68cb4e10
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/tabbedcontent.directive.js
@@ -0,0 +1,38 @@
+(function () {
+ 'use strict';
+
+ function tabbedContentDirective() {
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/content/tabbed-content.html',
+ controller: function ($scope) {
+
+ //expose the property/methods for other directives to use
+ this.content = $scope.content;
+
+ },
+ link: function(scope) {
+
+ function onInit() {
+ angular.forEach(scope.content.tabs, function (group) {
+ group.open = true;
+ });
+ }
+
+ onInit();
+
+ },
+ scope: {
+ content: "="
+ }
+ };
+
+ return directive;
+
+ }
+
+ angular.module('umbraco.directives').directive('tabbedContent', tabbedContentDirective);
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
index 71c59860df..f3ba2a048d 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js
@@ -12,10 +12,7 @@
function valPropertyMsg(serverValidationManager) {
return {
- scope: {
- property: "="
- },
- require: ['^^form', '^^valFormManager'],
+ require: ['^^form', '^^valFormManager', '^^umbProperty', '^^tabbedContent'],
replace: true,
restrict: "E",
template: "
{{errorMsg}}
",
@@ -24,25 +21,31 @@ function valPropertyMsg(serverValidationManager) {
//the property form controller api
var formCtrl = ctrl[0];
-
//the valFormManager controller api
var valFormManager = ctrl[1];
+ //the property controller api
+ var umbPropCtrl = ctrl[2];
+ //the tabbed content controller api
+ var tabbedContent = ctrl[3];
+
+ var currentProperty = umbPropCtrl.property;
+ var currentCulture = tabbedContent.content.language.culture;
var watcher = null;
// Gets the error message to display
function getErrorMsg() {
//this can be null if no property was assigned
- if (scope.property) {
+ if (currentProperty) {
//first try to get the error msg from the server collection
- var err = serverValidationManager.getPropertyError(scope.property.alias, "");
+ var err = serverValidationManager.getPropertyError(currentProperty.alias, null, "");
//if there's an error message use it
if (err && err.errorMsg) {
return err.errorMsg;
}
else {
//TODO: localize
- return scope.property.propertyErrorMessage ? scope.property.propertyErrorMessage : "Property has errors";
+ return currentProperty.propertyErrorMessage ? currentProperty.propertyErrorMessage : "Property has errors";
}
}
@@ -59,8 +62,10 @@ function valPropertyMsg(serverValidationManager) {
function startWatch() {
//if there's not already a watch
if (!watcher) {
- watcher = scope.$watch("property.value", function (newValue, oldValue) {
-
+ watcher = scope.$watch(function () {
+ return currentProperty.value;
+ }, function (newValue, oldValue) {
+
if (!newValue || angular.equals(newValue, oldValue)) {
return;
}
@@ -133,7 +138,7 @@ function valPropertyMsg(serverValidationManager) {
});
//listen for the forms saving event
- unsubscribe.push(scope.$on("formSubmitting", function(ev, args) {
+ unsubscribe.push(scope.$on("formSubmitting", function (ev, args) {
showValidation = true;
if (hasError && scope.errorMsg === "") {
scope.errorMsg = getErrorMsg();
@@ -145,7 +150,7 @@ function valPropertyMsg(serverValidationManager) {
}));
//listen for the forms saved event
- unsubscribe.push(scope.$on("formSubmitted", function(ev, args) {
+ unsubscribe.push(scope.$on("formSubmitted", function (ev, args) {
showValidation = false;
scope.errorMsg = "";
formCtrl.$setValidity('valPropertyMsg', true);
@@ -160,8 +165,8 @@ function valPropertyMsg(serverValidationManager) {
// indicate that a content property is invalid at the property level since developers may not actually implement
// the correct field validation in their property editors.
- if (scope.property) { //this can be null if no property was assigned
- serverValidationManager.subscribe(scope.property.alias, "", function (isValid, propertyErrors, allErrors) {
+ if (currentProperty) { //this can be null if no property was assigned
+ serverValidationManager.subscribe(currentProperty.alias, currentCulture, "", function (isValid, propertyErrors, allErrors) {
hasError = !isValid;
if (hasError) {
//set the error message to the server message
@@ -183,7 +188,7 @@ function valPropertyMsg(serverValidationManager) {
// but they are a different callback instance than the above.
element.bind('$destroy', function () {
stopWatch();
- serverValidationManager.unsubscribe(scope.property.alias, "");
+ serverValidationManager.unsubscribe(currentProperty.alias, currentCulture, "");
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
index 1432a713c0..b4492f8099 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserver.directive.js
@@ -7,13 +7,14 @@
**/
function valServer(serverValidationManager) {
return {
- require: ['ngModel', '?^umbProperty'],
+ require: ['ngModel', '?^^umbProperty', '?^^tabbedContent'],
restrict: "A",
link: function (scope, element, attr, ctrls) {
var modelCtrl = ctrls[0];
var umbPropCtrl = ctrls.length > 1 ? ctrls[1] : null;
- if (!umbPropCtrl) {
+ var tabbedContent = ctrls.length > 2 ? ctrls[2] : null;
+ if (!umbPropCtrl || !tabbedContent) {
//we cannot proceed, this validator will be disabled
return;
}
@@ -54,6 +55,7 @@ function valServer(serverValidationManager) {
}
var currentProperty = umbPropCtrl.property;
+ var currentCulture = tabbedContent.content.language.culture;
//default to 'value' if nothing is set
var fieldName = "value";
@@ -66,7 +68,7 @@ function valServer(serverValidationManager) {
}
//subscribe to the server validation changes
- serverValidationManager.subscribe(currentProperty.alias, fieldName, function (isValid, propertyErrors, allErrors) {
+ serverValidationManager.subscribe(currentProperty.alias, currentCulture, fieldName, function (isValid, propertyErrors, allErrors) {
if (!isValid) {
modelCtrl.$setValidity('valServer', false);
//assign an error msg property to the current validator
@@ -86,9 +88,9 @@ function valServer(serverValidationManager) {
// but they are a different callback instance than the above.
element.bind('$destroy', function () {
stopWatch();
- serverValidationManager.unsubscribe(currentProperty.alias, fieldName);
+ serverValidationManager.unsubscribe(currentProperty.alias, currentCulture, fieldName);
});
}
};
}
-angular.module('umbraco.directives.validation').directive("valServer", valServer);
\ No newline at end of file
+angular.module('umbraco.directives.validation').directive("valServer", valServer);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js
index 29fd94ff5b..d170670d15 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valserverfield.directive.js
@@ -33,7 +33,7 @@ function valServerField(serverValidationManager) {
}));
//subscribe to the server validation changes
- serverValidationManager.subscribe(null, fieldName, function (isValid, fieldErrors, allErrors) {
+ serverValidationManager.subscribe(null, null, fieldName, function (isValid, fieldErrors, allErrors) {
if (!isValid) {
ngModel.$setValidity('valServerField', false);
//assign an error msg property to the current validator
@@ -50,7 +50,7 @@ function valServerField(serverValidationManager) {
// NOTE: this is very important otherwise when this controller re-binds the previous subscriptsion will remain
// but they are a different callback instance than the above.
element.bind('$destroy', function () {
- serverValidationManager.unsubscribe(null, fieldName);
+ serverValidationManager.unsubscribe(null, null, fieldName);
});
}
});
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js
index ac90a0d333..64ddf8c228 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js
@@ -145,32 +145,33 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
// that each property is a User Developer property editor.
// The way that Content Type Editor ModelState is created is simply based on the ASP.Net validation data-annotations
// system.
- // So, to do this (since we need to support backwards compat), we need to hack a little bit. For Content Properties,
- // which are user defined, we know that they will exist with a prefixed ModelState of "_Properties.", so if we detect
- // this, then we know it's a Property.
+ // So, to do this there's some special ModelState syntax we need to know about.
+ // For Content Properties, which are user defined, we know that they will exist with a prefixed
+ // ModelState of "_Properties.", so if we detect this, then we know it's for a content Property.
//the alias in model state can be in dot notation which indicates
// * the first part is the content property alias
// * the second part is the field to which the valiation msg is associated with
- //There will always be at least 2 parts for properties since all model errors for properties are prefixed with "Properties"
- //If it is not prefixed with "Properties" that means the error is for a field of the object directly.
+ //There will always be at least 3 parts for content properties since all model errors for properties are prefixed with "_Properties"
+ //If it is not prefixed with "_Properties" that means the error is for a field of the object directly.
var parts = e.split(".");
//Check if this is for content properties - specific to content/media/member editors because those are special
// user defined properties with custom controls.
- if (parts.length > 1 && parts[0] === "_Properties") {
+ if (parts.length > 2 && parts[0] === "_Properties") {
var propertyAlias = parts[1];
+ var culture = parts[2];
- //if it contains 2 '.' then we will wire it up to a property's field
- if (parts.length > 2) {
+ //if it contains 3 '.' then we will wire it up to a property's html field
+ if (parts.length > 3) {
//add an error with a reference to the field for which the validation belongs too
- serverValidationManager.addPropertyError(propertyAlias, parts[2], modelState[e][0]);
+ serverValidationManager.addPropertyError(propertyAlias, culture, parts[3], modelState[e][0]);
}
else {
- //add a generic error for the property, no reference to a specific field
- serverValidationManager.addPropertyError(propertyAlias, "", modelState[e][0]);
+ //add a generic error for the property, no reference to a specific html field
+ serverValidationManager.addPropertyError(propertyAlias, culture, "", 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 d7e34d0f1c..41af17148b 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,11 +28,11 @@ function serverValidationManager($timeout) {
//find errors for this field name
return _.filter(self.items, function (item) {
- return (item.propertyAlias === null && item.fieldName === fieldName);
+ return (item.propertyAlias === null && item.culture === null && item.fieldName === fieldName);
});
}
- function getPropertyErrors(self, propertyAlias, fieldName) {
+ function getPropertyErrors(self, propertyAlias, culture, fieldName) {
if (!angular.isString(propertyAlias)) {
throw "propertyAlias must be a string";
}
@@ -42,7 +42,7 @@ function serverValidationManager($timeout) {
//find all errors for this property
return _.filter(self.items, function (item) {
- return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
+ return (item.propertyAlias === propertyAlias && item.culture === culture && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
}
@@ -104,7 +104,7 @@ function serverValidationManager($timeout) {
* field alias to listen for.
* If propertyAlias is null, then this subscription is for a field property (not a user defined property).
*/
- subscribe: function (propertyAlias, fieldName, callback) {
+ subscribe: function (propertyAlias, culture, fieldName, callback) {
if (!callback) {
return;
}
@@ -115,41 +115,46 @@ function serverValidationManager($timeout) {
return item.propertyAlias === null && item.fieldName === fieldName;
});
if (!exists1) {
- callbacks.push({ propertyAlias: null, fieldName: fieldName, callback: callback });
+ callbacks.push({ propertyAlias: null, culture: null, fieldName: fieldName, callback: callback });
}
}
else if (propertyAlias !== undefined) {
+ if (!culture) {
+ culture = null; // if empty or null, always make null
+ }
//don't add it if it already exists
var exists2 = _.find(callbacks, function (item) {
- return item.propertyAlias === propertyAlias && item.fieldName === fieldName;
+ return item.propertyAlias === propertyAlias && item.culture === culture && item.fieldName === fieldName;
});
if (!exists2) {
- callbacks.push({ propertyAlias: propertyAlias, fieldName: fieldName, callback: callback });
+ callbacks.push({ propertyAlias: propertyAlias, culture: culture, fieldName: fieldName, callback: callback });
}
}
},
- unsubscribe: function (propertyAlias, fieldName) {
+ unsubscribe: function (propertyAlias, culture, fieldName) {
if (propertyAlias === null) {
//remove all callbacks for the content field
callbacks = _.reject(callbacks, function (item) {
- return item.propertyAlias === null && item.fieldName === fieldName;
+ return item.propertyAlias === null && item.culture === null && item.fieldName === fieldName;
});
}
else if (propertyAlias !== undefined) {
-
+
+ if (!culture) {
+ culture = null; // if empty or null, always make null
+ }
+
//remove all callbacks for the content property
callbacks = _.reject(callbacks, function (item) {
- return item.propertyAlias === propertyAlias &&
+ return item.propertyAlias === propertyAlias && item.culture === culture &&
(item.fieldName === fieldName ||
((item.fieldName === undefined || item.fieldName === "") && (fieldName === undefined || fieldName === "")));
});
}
-
-
},
@@ -164,10 +169,15 @@ function serverValidationManager($timeout) {
* 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 (propertyAlias, fieldName) {
+ getPropertyCallbacks: function (propertyAlias, culture, fieldName) {
+
+ if (!culture) {
+ culture = null; // if empty or null, always make null
+ }
+
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 === propertyAlias && (item.fieldName === fieldName || (item.fieldName === undefined || item.fieldName === "")));
+ return (item.propertyAlias === propertyAlias && item.culture === culture && (item.fieldName === fieldName || (item.fieldName === undefined || item.fieldName === "")));
});
return found;
},
@@ -184,7 +194,7 @@ function serverValidationManager($timeout) {
getFieldCallbacks: function (fieldName) {
var found = _.filter(callbacks, function (item) {
//returns any callback that have been registered directly against the field
- return (item.propertyAlias === null && item.fieldName === fieldName);
+ return (item.propertyAlias === null && item.culture === null && item.fieldName === fieldName);
});
return found;
},
@@ -207,6 +217,7 @@ function serverValidationManager($timeout) {
if (!this.hasFieldError(fieldName)) {
this.items.push({
propertyAlias: null,
+ culture: null,
fieldName: fieldName,
errorMsg: errorMsg
});
@@ -231,24 +242,29 @@ function serverValidationManager($timeout) {
* @description
* Adds an error message for the content property
*/
- addPropertyError: function (propertyAlias, fieldName, errorMsg) {
+ addPropertyError: function (propertyAlias, culture, fieldName, errorMsg) {
if (!propertyAlias) {
return;
}
-
+
+ if (!culture) {
+ culture = null; // if empty or null, always make null
+ }
+
//only add the item if it doesn't exist
- if (!this.hasPropertyError(propertyAlias, fieldName)) {
+ if (!this.hasPropertyError(propertyAlias, culture, fieldName)) {
this.items.push({
propertyAlias: propertyAlias,
+ culture: culture,
fieldName: fieldName,
errorMsg: errorMsg
});
}
//find all errors for this item
- var errorsForCallback = getPropertyErrors(this, propertyAlias, fieldName);
+ var errorsForCallback = getPropertyErrors(this, propertyAlias, culture, fieldName);
//we should now call all of the call backs registered for this error
- var cbs = this.getPropertyCallbacks(propertyAlias, fieldName);
+ var cbs = this.getPropertyCallbacks(propertyAlias, culture, fieldName);
//call each callback for this error
for (var cb in cbs) {
executeCallback(this, errorsForCallback, cbs[cb].callback);
@@ -264,14 +280,14 @@ function serverValidationManager($timeout) {
* @description
* Removes an error message for the content property
*/
- removePropertyError: function (propertyAlias, fieldName) {
+ removePropertyError: function (propertyAlias, culture, fieldName) {
if (!propertyAlias) {
return;
}
//remove the item
this.items = _.reject(this.items, function (item) {
- return (item.propertyAlias === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
+ return (item.propertyAlias === propertyAlias && item.culture === culture && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
},
@@ -316,10 +332,10 @@ function serverValidationManager($timeout) {
* @description
* Gets the error message for the content property
*/
- getPropertyError: function (propertyAlias, fieldName) {
+ getPropertyError: function (propertyAlias, culture, 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 === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
+ return (item.propertyAlias === propertyAlias && item.culture === culture && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
return err;
},
@@ -336,7 +352,7 @@ function serverValidationManager($timeout) {
getFieldError: function (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 === null && item.fieldName === fieldName);
+ return (item.propertyAlias === null && item.culture === null && item.fieldName === fieldName);
});
return err;
},
@@ -348,12 +364,12 @@ function serverValidationManager($timeout) {
* @function
*
* @description
- * Checks if the content property + field name combo has an error
+ * Checks if the content property + culture + field name combo has an error
*/
- hasPropertyError: function (propertyAlias, fieldName) {
+ hasPropertyError: function (propertyAlias, culture, 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 === propertyAlias && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
+ return (item.propertyAlias === propertyAlias && item.culture === culture && (item.fieldName === fieldName || (fieldName === undefined || fieldName === "")));
});
return err ? true : false;
},
@@ -370,7 +386,7 @@ function serverValidationManager($timeout) {
hasFieldError: function (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 === null && item.fieldName === fieldName);
+ return (item.propertyAlias === null && item.culture === null && item.fieldName === fieldName);
});
return err ? true : false;
},
@@ -380,4 +396,4 @@ function serverValidationManager($timeout) {
};
}
-angular.module('umbraco.services').factory('serverValidationManager', serverValidationManager);
\ No newline at end of file
+angular.module('umbraco.services').factory('serverValidationManager', serverValidationManager);
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/tabbed-content.html b/src/Umbraco.Web.UI.Client/src/views/components/content/tabbed-content.html
new file mode 100644
index 0000000000..eb7a541a42
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/components/content/tabbed-content.html
@@ -0,0 +1,17 @@
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property.html b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property.html
index 24bc1de6ed..a6f2096002 100644
--- a/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property.html
+++ b/src/Umbraco.Web.UI.Client/src/views/components/property/umb-property.html
@@ -2,7 +2,7 @@
-
\ No newline at end of file
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.controller.js
index 3e30b25a94..cb3f0e6be3 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.controller.js
@@ -6,14 +6,9 @@
var vm = this;
vm.loading = true;
+ //TODO: Figure out what we need to do to maintain validation states since this will re-init the editor
function onInit() {
-
vm.content = $scope.model.viewModel;
-
- angular.forEach(vm.content.tabs, function (group) {
- group.open = true;
- });
-
vm.loading = false;
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.html b/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.html
index db71539c59..76d939a81e 100644
--- a/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.html
+++ b/src/Umbraco.Web.UI.Client/src/views/content/apps/content/content.html
@@ -1,18 +1,5 @@
diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/server-validation-manager.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/server-validation-manager.spec.js
index 2740bd7317..7510b766a8 100644
--- a/src/Umbraco.Web.UI.Client/test/unit/common/services/server-validation-manager.spec.js
+++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/server-validation-manager.spec.js
@@ -60,12 +60,12 @@
it('can retrieve property validation errors for a sub field', function () {
//arrange
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Another value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Another value 2");
//act
- var err1 = serverValidationManager.getPropertyError("myProperty", "value1");
- var err2 = serverValidationManager.getPropertyError("myProperty", "value2");
+ var err1 = serverValidationManager.getPropertyError("myProperty", null, "value1");
+ var err2 = serverValidationManager.getPropertyError("myProperty", null, "value2");
//assert
expect(err1).not.toBeUndefined();
@@ -82,8 +82,8 @@
it('can add a property errors with multiple sub fields and it the first will be retreived with only the property alias', function () {
//arrange
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Another value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Another value 2");
//act
var err = serverValidationManager.getPropertyError("myProperty");
@@ -98,10 +98,10 @@
it('will return null for a non-existing property error', function () {
//arrage
- serverValidationManager.addPropertyError("myProperty", "value", "Required");
+ serverValidationManager.addPropertyError("myProperty", null, "value", "Required");
//act
- var err = serverValidationManager.getPropertyError("DoesntExist", "value");
+ var err = serverValidationManager.getPropertyError("DoesntExist", null, "value");
//assert
expect(err).toBeUndefined();
@@ -111,15 +111,15 @@
it('detects if a property error exists', function () {
//arrange
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Another value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Another value 2");
//act
var err1 = serverValidationManager.hasPropertyError("myProperty");
- var err2 = serverValidationManager.hasPropertyError("myProperty", "value1");
- var err3 = serverValidationManager.hasPropertyError("myProperty", "value2");
+ var err2 = serverValidationManager.hasPropertyError("myProperty", null, "value1");
+ var err3 = serverValidationManager.hasPropertyError("myProperty", null, "value2");
var err4 = serverValidationManager.hasPropertyError("notFound");
- var err5 = serverValidationManager.hasPropertyError("myProperty", "notFound");
+ var err5 = serverValidationManager.hasPropertyError("myProperty", null, "notFound");
//assert
expect(err1).toBe(true);
@@ -133,30 +133,30 @@
it('can remove a property error with a sub field specified', function () {
//arrage
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Another value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Another value 2");
//act
- serverValidationManager.removePropertyError("myProperty", "value1");
+ serverValidationManager.removePropertyError("myProperty", null, "value1");
//assert
- expect(serverValidationManager.hasPropertyError("myProperty", "value1")).toBe(false);
- expect(serverValidationManager.hasPropertyError("myProperty", "value2")).toBe(true);
+ expect(serverValidationManager.hasPropertyError("myProperty", null, "value1")).toBe(false);
+ expect(serverValidationManager.hasPropertyError("myProperty", null, "value2")).toBe(true);
});
it('can remove a property error and all sub field errors by specifying only the property', function () {
//arrage
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Another value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Another value 2");
//act
serverValidationManager.removePropertyError("myProperty");
//assert
- expect(serverValidationManager.hasPropertyError("myProperty", "value1")).toBe(false);
- expect(serverValidationManager.hasPropertyError("myProperty", "value2")).toBe(false);
+ expect(serverValidationManager.hasPropertyError("myProperty", null, "value1")).toBe(false);
+ expect(serverValidationManager.hasPropertyError("myProperty", null, "value2")).toBe(false);
});
@@ -168,7 +168,7 @@
var args;
//arrange
- serverValidationManager.subscribe(null, "Name", function (isValid, propertyErrors, allErrors) {
+ serverValidationManager.subscribe(null, null, "Name", function (isValid, propertyErrors, allErrors) {
args = {
isValid: isValid,
propertyErrors: propertyErrors,
@@ -178,7 +178,7 @@
//act
serverValidationManager.addFieldError("Name", "Required");
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
//assert
expect(args).not.toBeUndefined();
@@ -195,8 +195,8 @@
};
var cb2 = function () {
};
- serverValidationManager.subscribe(null, "Name", cb1);
- serverValidationManager.subscribe(null, "Title", cb2);
+ serverValidationManager.subscribe(null, null, "Name", cb1);
+ serverValidationManager.subscribe(null, null, "Title", cb2);
//act
serverValidationManager.addFieldError("Name", "Required");
@@ -224,7 +224,7 @@
var numCalled = 0;
//arrange
- serverValidationManager.subscribe("myProperty", "value1", function (isValid, propertyErrors, allErrors) {
+ serverValidationManager.subscribe("myProperty", null, "value1", function (isValid, propertyErrors, allErrors) {
args1 = {
isValid: isValid,
propertyErrors: propertyErrors,
@@ -232,7 +232,7 @@
};
});
- serverValidationManager.subscribe("myProperty", "", function (isValid, propertyErrors, allErrors) {
+ serverValidationManager.subscribe("myProperty", null, "", function (isValid, propertyErrors, allErrors) {
numCalled++;
args2 = {
isValid: isValid,
@@ -242,9 +242,9 @@
});
//act
- serverValidationManager.addPropertyError("myProperty", "value1", "Some value 1");
- serverValidationManager.addPropertyError("myProperty", "value2", "Some value 2");
- serverValidationManager.addPropertyError("myProperty", "", "Some value 3");
+ serverValidationManager.addPropertyError("myProperty", null, "value1", "Some value 1");
+ serverValidationManager.addPropertyError("myProperty", null, "value2", "Some value 2");
+ serverValidationManager.addPropertyError("myProperty", null, "", "Some value 3");
//assert
expect(args1).not.toBeUndefined();
@@ -272,4 +272,4 @@
});
-});
\ No newline at end of file
+});
diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
index 4f419ccece..98ad4ea404 100644
--- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml
@@ -2063,6 +2063,9 @@ To manage your website, simply open the Umbraco back office and start adding con
Invalid date
Not a number
Invalid email
+ Value cannot be null
+ Value cannot be empty
+ Value is invalid, it does not match the correct pattern