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 119f6202db..42a9214cb6 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 @@ -99,12 +99,20 @@ function valPropertyMsg(serverValidationManager) { // the form. Of course normal client-side validators will continue to execute. scope.$watch("property.value", function (newValue) { //we are explicitly checking for valServer errors here, since we shouldn't auto clear - // based on other errors. - if (formCtrl.$invalid && scope.formCtrl.$error.valServer !== undefined) { + // based on other errors. We'll also check if there's no other validation errors apart from valPropertyMsg, if valPropertyMsg + // is the only one, then we'll clear. + + var errCount = 0; + for (var e in scope.formCtrl.$error) { + errCount++; + } + + if ((errCount === 1 && scope.formCtrl.$error.valPropertyMsg !== undefined) || + (formCtrl.$invalid && scope.formCtrl.$error.valServer !== undefined)) { scope.errorMsg = ""; formCtrl.$setValidity('valPropertyMsg', true); } - }); + }, true); //listen for server validation changes // NOTE: we pass in "" in order to listen for all validation changes to the content property, not for diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index a33fea33b3..ae1f67aea3 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -77,4 +77,8 @@ @import "animations.less"; @import "font-awesome.min.less"; // Remove when Helveticons/fontcustom is ready // @import "fontcustom.less"; + +//used for property editors +@import "property-editors.less"; + @import "hacks.less"; // Remove and rewrite before release diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less new file mode 100644 index 0000000000..bc6c40d1be --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -0,0 +1,17 @@ +// +// Color picker +// -------------------------------------------------- + +ul.color-picker li { + padding: 2px; + margin: 3px; + border: 2px solid transparent; +} +ul.color-picker li.active { + border: 2px dashed #d9d9d9; +} +ul.color-picker li a { + height: 50px; + display:block; + cursor:pointer; +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js new file mode 100644 index 0000000000..ddb392c910 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.controller.js @@ -0,0 +1,8 @@ +angular.module("umbraco").controller("Umbraco.Editors.ColorPickerController", + function($scope) { + + $scope.selectItem = function(color) { + $scope.model.value = color; + }; + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html new file mode 100644 index 0000000000..f58fc39dc4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/colorpicker/colorpicker.html @@ -0,0 +1,11 @@ +
+ + + +
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.controller.js index 2d3d208a35..b43272ac50 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.controller.js @@ -22,12 +22,6 @@ angular.module("umbraco").controller("Umbraco.Editors.DropdownPreValueController return i === item; }); - //setup the dictionary from array - $scope.model.value = {}; - for (var i = 0; i < $scope.model.value.length; i++) { - //just make the key the iteration - $scope.model.value[i] = $scope.model.value[i]; - } }; $scope.add = function (evt) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.html index 440fa629db..97233f7921 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.prevalue.html @@ -8,6 +8,6 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textstring/textstring.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html similarity index 100% rename from src/Umbraco.Web.UI.Client/src/views/propertyeditors/textstring/textstring.html rename to src/Umbraco.Web.UI.Client/src/views/propertyeditors/textbox/textbox.html diff --git a/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs b/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs index ee5c2447a9..1d6d2f5b12 100644 --- a/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs +++ b/src/Umbraco.Web/Editors/DataTypeValidateAttribute.cs @@ -88,7 +88,7 @@ namespace Umbraco.Web.Editors foreach (var v in propertyEditor.PreValueEditor.Fields.SelectMany(x => x.Validators)) { - foreach (var result in v.Validate(postedValue != null ? postedValue.ToString() : null, preVal.Key, propertyEditor)) + foreach (var result in v.Validate(postedValue, preVal.Key, propertyEditor)) { //if there are no member names supplied then we assume that the validation message is for the overall property // not a sub field on the property editor diff --git a/src/Umbraco.Web/PropertyEditors/ColorPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ColorPickerPropertyEditor.cs new file mode 100644 index 0000000000..e79d4a9552 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/ColorPickerPropertyEditor.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json.Linq; +using Umbraco.Core; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + [PropertyEditor(Constants.PropertyEditors.ColorPicker, "Color Picker", "colorpicker")] + public class ColorPickerPropertyEditor : PropertyEditor + { + /// + /// Return a custom pre-value editor + /// + /// + /// + /// We are just going to re-use the ValueListPreValueEditor + /// + protected override PreValueEditor CreatePreValueEditor() + { + return new ColorListPreValueEditor(); + } + + } + + internal class ColorListPreValueEditor : ValueListPreValueEditor + { + public ColorListPreValueEditor() + { + var fields = CreatePreValueFields(); + //change the description + fields.First().Description = "Add and remove colors in HEX format without a prefixed '#'"; + //need to have some custom validation happening here + fields.First().Validators = new List + { + new ColorListValidator() + }; + + Fields = fields; + } + + internal class ColorListValidator : ValidatorBase + { + public override IEnumerable Validate(object value, string preValues, PropertyEditor editor) + { + var json = value as JArray; + if (json != null) + { + //validate each item + foreach (var i in json) + { + //NOTE: we will be removing empty values when persisting so no need to validate + var asString = i.ToString(); + if (asString.IsNullOrWhiteSpace() == false) + { + if (Regex.IsMatch(asString, "^([0-9a-f]{3}|[0-9a-f]{6})$", RegexOptions.IgnoreCase) == false) + { + yield return new ValidationResult("The value " + asString + " is not a valid hex color", new[] + { + //we'll make the server field name the value of the hex color so we can wire it back up to the + //individual row in the UI. + asString + }); + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/TextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/TextStringPropertyEditor.cs index 313b8e4826..32b283b0c3 100644 --- a/src/Umbraco.Web/PropertyEditors/TextStringPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/TextStringPropertyEditor.cs @@ -4,11 +4,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.Textbox, "Textstring", "textstring")] + [PropertyEditor(Constants.PropertyEditors.Textbox, "Textbox", "textbox")] public class TextStringPropertyEditor : PropertyEditor { } diff --git a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs index f815338066..f408526b53 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs @@ -91,6 +91,12 @@ namespace Umbraco.Web.PropertyEditors var index = 0; foreach (var item in val) { + var asString = item.ToString(); + //don't allow empties + if (asString.IsNullOrWhiteSpace()) + { + continue; + } result.Add(index.ToInvariantString(), item.ToString()); index++; } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 538ca92263..c89ad2db3d 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -316,6 +316,7 @@ +