diff --git a/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs b/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs index 757e09f30f..33c2c02cb6 100644 --- a/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/RequiredManifestValueValidator.cs @@ -21,6 +21,15 @@ namespace Umbraco.Core.PropertyEditors else { var asString = value.ToString(); + + if (editor.ValueEditor.ValueType.InvariantEquals("JSON")) + { + if (asString.DetectIsEmptyJson()) + { + yield return new ValidationResult("Value cannot be empty", new[] { "value" }); + } + } + if (asString.IsNullOrWhiteSpace()) { yield return new ValidationResult("Value cannot be empty", new[] { "value" }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js index 62cf96a894..4577430195 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/tags/tags.controller.js @@ -34,6 +34,9 @@ angular.module("umbraco") if (tagToAdd.length > 0) { if ($scope.currentTags.indexOf(tagToAdd) < 0) { $scope.currentTags.push(tagToAdd); + //update the model value, this is required if there's a server validation error, it can + // only then be cleared if the model changes + $scope.model.value = $scope.currentTags; } } } @@ -66,6 +69,9 @@ angular.module("umbraco") var i = $scope.currentTags.indexOf(tag); if (i >= 0) { $scope.currentTags.splice(i, 1); + //update the model value, this is required if there's a server validation error, it can + // only then be cleared if the model changes + $scope.model.value = $scope.currentTags; } }; diff --git a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs index 49fb5ddbc4..581186f61d 100644 --- a/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TagsPropertyEditor.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Runtime.InteropServices; using Newtonsoft.Json.Linq; @@ -61,6 +62,61 @@ namespace Umbraco.Web.PropertyEditors var json = editorValue.Value as JArray; return json == null ? null : json.Select(x => x.Value()); } + + /// + /// Returns the validator used for the required field validation which is specified on the PropertyType + /// + /// + /// This will become legacy as soon as we implement overridable pre-values. + /// + /// The default validator used is the RequiredValueValidator but this can be overridden by property editors + /// if they need to do some custom validation, or if the value being validated is a json object. + /// + internal override ManifestValueValidator RequiredValidator + { + get { return new RequiredTagsValueValidator(); } + } + + /// + /// Custom validator to validate a required value against an empty json value + /// + /// + /// This is required because the Tags property editor is not of type 'JSON', it's just string so the underlying + /// validator does not validate against an empty json string + /// + [ValueValidator("Required")] + private class RequiredTagsValueValidator : ManifestValueValidator + { + /// + /// Validates a null value or an empty json value + /// + /// + /// + /// + /// + /// + public override IEnumerable Validate(object value, string config, PreValueCollection preValues, PropertyEditor editor) + { + if (value == null) + { + yield return new ValidationResult("Value cannot be null", new[] { "value" }); + } + else + { + var asString = value.ToString(); + + if (asString.DetectIsEmptyJson()) + { + yield return new ValidationResult("Value cannot be empty", new[] { "value" }); + } + + if (asString.IsNullOrWhiteSpace()) + { + yield return new ValidationResult("Value cannot be empty", new[] { "value" }); + } + } + } + } } internal class TagPreValueEditor : PreValueEditor