From 976e1e8a35be93993e6d7cf71926fc90af18d9d1 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Thu, 1 Mar 2018 14:25:07 +0100 Subject: [PATCH 1/8] Mark existing dropdown property editors as obsolete --- .../PropertyEditors/DropDownMultiplePropertyEditor.cs | 4 ++-- .../PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs | 4 ++-- src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs | 4 ++-- .../PropertyEditors/DropDownWithKeysPropertyEditor.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs index a4dfd6c2ad..5cfd745d62 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs @@ -15,7 +15,7 @@ namespace Umbraco.Web.PropertyEditors [ParameterEditor("propertyTypePickerMultiple", "Name", "textbox")] [ParameterEditor("contentTypeMultiple", "Name", "textbox")] [ParameterEditor("tabPickerMultiple", "Name", "textbox")] - [PropertyEditor(Constants.PropertyEditors.DropDownListMultipleAlias, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list")] + [PropertyEditor(Constants.PropertyEditors.DropDownListMultipleAlias, "Dropdown list multiple", "dropdown", Group = "lists", Icon="icon-bulleted-list", IsDeprecated = true)] public class DropDownMultiplePropertyEditor : DropDownMultipleWithKeysPropertyEditor { protected override PropertyValueEditor CreateValueEditor() @@ -28,4 +28,4 @@ namespace Umbraco.Web.PropertyEditors -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs index 05ba3e2644..ac28379f0d 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownMultipleWithKeysPropertyEditor.cs @@ -12,7 +12,7 @@ namespace Umbraco.Web.PropertyEditors /// Due to maintaining backwards compatibility this data type stores the value as a string which is a comma separated value of the /// ids of the individual items so we have logic in here to deal with that. /// - [PropertyEditor(Constants.PropertyEditors.DropdownlistMultiplePublishKeysAlias, "Dropdown list multiple, publish keys", "dropdown", Group = "lists", Icon = "icon-bulleted-list")] + [PropertyEditor(Constants.PropertyEditors.DropdownlistMultiplePublishKeysAlias, "Dropdown list multiple, publish keys", "dropdown", Group = "lists", Icon = "icon-bulleted-list", IsDeprecated = true)] public class DropDownMultipleWithKeysPropertyEditor : DropDownPropertyEditor { protected override PropertyValueEditor CreateValueEditor() @@ -62,4 +62,4 @@ namespace Umbraco.Web.PropertyEditors } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs index 115b99dea4..4c9b0ae99a 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs @@ -16,7 +16,7 @@ namespace Umbraco.Web.PropertyEditors /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the string value is published /// in cache and not the int ID. /// - [PropertyEditor(Constants.PropertyEditors.DropDownListAlias, "Dropdown list", "dropdown", ValueType = PropertyEditorValueTypes.String, Group = "lists", Icon = "icon-indent")] + [PropertyEditor(Constants.PropertyEditors.DropDownListAlias, "Dropdown list", "dropdown", ValueType = PropertyEditorValueTypes.String, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor { /// @@ -29,4 +29,4 @@ namespace Umbraco.Web.PropertyEditors } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs index a33115003c..4e8efd93a5 100644 --- a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs @@ -11,7 +11,7 @@ namespace Umbraco.Web.PropertyEditors /// as INT and we have logic in here to ensure it is formatted correctly including ensuring that the INT ID value is published /// in cache and not the string value. /// - [PropertyEditor(Constants.PropertyEditors.DropdownlistPublishingKeysAlias, "Dropdown list, publishing keys", "dropdown", ValueType = PropertyEditorValueTypes.Integer, Group = "lists", Icon = "icon-indent")] + [PropertyEditor(Constants.PropertyEditors.DropdownlistPublishingKeysAlias, "Dropdown list, publishing keys", "dropdown", ValueType = PropertyEditorValueTypes.Integer, Group = "lists", Icon = "icon-indent", IsDeprecated = true)] public class DropDownWithKeysPropertyEditor : PropertyEditor { @@ -24,4 +24,4 @@ namespace Umbraco.Web.PropertyEditors return new ValueListPreValueEditor(); } } -} \ No newline at end of file +} From 466de5ee0bf6d2b28440c72e34c407d0badb6479 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Thu, 1 Mar 2018 14:41:44 +0100 Subject: [PATCH 2/8] Adds a label to the boolean pre value editor --- .../src/views/prevalueeditors/boolean.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html index 8af17a18ea..79539e2f81 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html @@ -1 +1 @@ - \ No newline at end of file + From d06b7edd849a17393d169996141f59260ce746f3 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Thu, 1 Mar 2018 14:46:36 +0100 Subject: [PATCH 3/8] Change default value label to "true" --- .../src/views/prevalueeditors/boolean.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html index 79539e2f81..3e6be09650 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html @@ -1 +1 @@ - + From ceb3ae361afabc0b1cd353fed4bd9a620314bdc0 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Tue, 6 Mar 2018 11:07:08 +0100 Subject: [PATCH 4/8] Adds flexible dropdown editor to replace the four current ones --- src/Umbraco.Core/Constants-PropertyEditors.cs | 7 +- .../dropdownFlexible.controller.js | 81 ++++++++++++++++++ .../dropdownFlexible/dropdownFlexible.html | 19 +++++ .../DropdownFlexiblePropertyEditor.cs | 83 +++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 5 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html create mode 100644 src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs diff --git a/src/Umbraco.Core/Constants-PropertyEditors.cs b/src/Umbraco.Core/Constants-PropertyEditors.cs index 1f3986eeaf..43779ea44a 100644 --- a/src/Umbraco.Core/Constants-PropertyEditors.cs +++ b/src/Umbraco.Core/Constants-PropertyEditors.cs @@ -122,6 +122,11 @@ namespace Umbraco.Core /// Alias for the Dropdown list, publishing keys datatype. /// public const string DropdownlistPublishingKeysAlias = "Umbraco.DropdownlistPublishingKeys"; + + /// + /// Alias for the "new" Dropdown list, that replaces the old four deprecated ones and works as other list based property editors + /// + public const string DropDownListFlexibleAlias = "Umbraco.DropDown.Flexible"; /// /// Guid for the Folder browser datatype. @@ -452,4 +457,4 @@ namespace Umbraco.Core } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js new file mode 100644 index 0000000000..72efc00738 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -0,0 +1,81 @@ +angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleController", + function($scope) { + + //setup the default config + var config = { + items: [], + multiple: false + }; + + //map the user config + angular.extend(config, $scope.model.config); + + //map back to the model + $scope.model.config = config; + + function convertArrayToDictionaryArray(model){ + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + for (var i = 0; i < model.length; i++) { + newItems.push({ id: model[i], sortOrder: 0, value: model[i] }); + } + + return newItems; + } + + + function convertObjectToDictionaryArray(model){ + //now we need to format the items in the dictionary because we always want to have an array + var newItems = []; + var vals = _.values($scope.model.config.items); + var keys = _.keys($scope.model.config.items); + + for (var i = 0; i < vals.length; i++) { + var label = vals[i].value ? vals[i].value : vals[i]; + newItems.push({ id: keys[i], sortOrder: vals[i].sortOrder, value: label }); + } + + return newItems; + } + + $scope.updateSingleDropdownValue = function() { + $scope.model.value = [$scope.model.singleDropdownValue]; + } + + if (angular.isArray($scope.model.config.items)) { + //PP: I dont think this will happen, but we have tests that expect it to happen.. + //if array is simple values, convert to array of objects + if(!angular.isObject($scope.model.config.items[0])){ + $scope.model.config.items = convertArrayToDictionaryArray($scope.model.config.items); + } + } + else if (angular.isObject($scope.model.config.items)) { + $scope.model.config.items = convertObjectToDictionaryArray($scope.model.config.items); + } + else { + throw "The items property must be either an array or a dictionary"; + } + + + //sort the values + $scope.model.config.items.sort(function (a, b) { return (a.sortOrder > b.sortOrder) ? 1 : ((b.sortOrder > a.sortOrder) ? -1 : 0); }); + + //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set + // to "" gets selected by default + if ($scope.model.value === null || $scope.model.value === undefined) { + if ($scope.model.config.multiple) { + $scope.model.value = []; + } + else { + $scope.model.value = ""; + } + } + + // if we run in single mode we'll store the value in a local variable + // so we can pass an array as the model as our PropertyValueEditor expects that + $scope.model.singleDropdownValue = ""; + if ($scope.model.config.multiple === false) { + $scope.model.singleDropdownValue = $scope.model.value; + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html new file mode 100644 index 0000000000..a68a614ad1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.html @@ -0,0 +1,19 @@ +
+ + + + + +
diff --git a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs new file mode 100644 index 0000000000..f64b48541d --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Umbraco.Core; +using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + [PropertyEditor(Constants.PropertyEditors.DropDownListFlexibleAlias, "Dropdown", "dropdownFlexible", Group = "lists", Icon = "icon-indent")] + public class DropdownFlexiblePropertyEditor : PropertyEditor + { + private static readonly string _multipleKey = "multiple"; + + /// + /// Return a custom pre-value editor + /// + /// + /// + /// We are just going to re-use the ValueListPreValueEditor + /// + protected override PreValueEditor CreatePreValueEditor() + { + return new DropdownFlexiblePreValueEditor(); + } + + /// + /// We need to override the value editor so that we can ensure the string value is published in cache and not the integer ID value. + /// + /// + protected override PropertyValueEditor CreateValueEditor() + { + return new PublishValuesMultipleValueEditor(false, base.CreateValueEditor()); + } + + internal class DropdownFlexiblePreValueEditor : ValueListPreValueEditor + { + public DropdownFlexiblePreValueEditor() + { + Fields.Insert(0, new PreValueField + { + Key = "multiple", + Name = "Enable multiple choice", + Description = "When checked, the dropdown will be a select multiple /combobox style dropdown", + View = "boolean" + }); + } + + public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue) + { + + var result = base.ConvertEditorToDb(editorValue, currentValue); + + // get multiple config + result.Add(_multipleKey, new PreValue(-1, editorValue[_multipleKey].ToString())); + + return result; + } + + public override IDictionary ConvertDbToEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals) + { + // weird way, but as the value stored is 0 or 1 need to do it this way + string multipleMode = "0"; + if (persistedPreVals != null && persistedPreVals.PreValuesAsDictionary[_multipleKey] != null) + { + multipleMode = persistedPreVals.PreValuesAsDictionary[_multipleKey].Value; + + // remove from the collection sent to the base multiple values collection + persistedPreVals.PreValuesAsDictionary.Remove(_multipleKey); + } + + var returnVal = base.ConvertDbToEditor(defaultPreVals, persistedPreVals); + + returnVal[_multipleKey] = multipleMode; + return returnVal; + } + + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index c6d528bb3d..d11475c0fb 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -337,6 +337,7 @@ + From 8e0565e03058c2caded49fb1b380d6704c491b95 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Tue, 6 Mar 2018 11:16:51 +0100 Subject: [PATCH 5/8] Fixes spacing in description :) --- .../PropertyEditors/DropdownFlexiblePropertyEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs index f64b48541d..717969575e 100644 --- a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.PropertyEditors { Key = "multiple", Name = "Enable multiple choice", - Description = "When checked, the dropdown will be a select multiple /combobox style dropdown", + Description = "When checked, the dropdown will be a select multiple / combobox style dropdown", View = "boolean" }); } From 05a9c44e9efabb453c62f29f535b5fb4303c7ce1 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Tue, 6 Mar 2018 11:51:32 +0100 Subject: [PATCH 6/8] Needs to check if single value is an array and then pick first value --- .../dropdownFlexible/dropdownFlexible.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js index 72efc00738..c7a472d80e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdownFlexible/dropdownFlexible.controller.js @@ -74,8 +74,8 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.DropdownFlexibleCo // if we run in single mode we'll store the value in a local variable // so we can pass an array as the model as our PropertyValueEditor expects that $scope.model.singleDropdownValue = ""; - if ($scope.model.config.multiple === false) { - $scope.model.singleDropdownValue = $scope.model.value; + if ($scope.model.config.multiple === "0") { + $scope.model.singleDropdownValue = Array.isArray($scope.model.value) ? $scope.model.value[0] : $scope.model.value; } }); From 5166dc08d6960b5fe70c225706ea8a1354e30426 Mon Sep 17 00:00:00 2001 From: Niels Hartvig Date: Tue, 6 Mar 2018 12:44:39 +0100 Subject: [PATCH 7/8] Missing null check --- .../PropertyEditors/DropdownFlexiblePropertyEditor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs index 717969575e..9e168ef3b4 100644 --- a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs @@ -55,7 +55,8 @@ namespace Umbraco.Web.PropertyEditors var result = base.ConvertEditorToDb(editorValue, currentValue); // get multiple config - result.Add(_multipleKey, new PreValue(-1, editorValue[_multipleKey].ToString())); + var multipleValue = editorValue[_multipleKey] != null ? editorValue[_multipleKey].ToString() : "0"; + result.Add(_multipleKey, new PreValue(-1, multipleValue)); return result; } From e4b77416a6a2a3e4db004919f8a810e052c4acce Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 19 Mar 2018 14:28:24 +0100 Subject: [PATCH 8/8] Fixed typo --- .../PropertyEditors/DropdownFlexiblePropertyEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs index 9e168ef3b4..236aa273c3 100644 --- a/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DropdownFlexiblePropertyEditor.cs @@ -44,7 +44,7 @@ namespace Umbraco.Web.PropertyEditors { Key = "multiple", Name = "Enable multiple choice", - Description = "When checked, the dropdown will be a select multiple / combobox style dropdown", + Description = "When checked, the dropdown will be a select multiple / combo box style dropdown", View = "boolean" }); }