diff --git a/src/Umbraco.Core/Models/PreValueCollection.cs b/src/Umbraco.Core/Models/PreValueCollection.cs index b8d882c112..9741869a50 100644 --- a/src/Umbraco.Core/Models/PreValueCollection.cs +++ b/src/Umbraco.Core/Models/PreValueCollection.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Models /// public class PreValueCollection { - private IDictionary _preValuesAsDictionary; + private IDictionary _preValuesAsDictionary; private IEnumerable _preValuesAsArray; public IEnumerable PreValuesAsArray { @@ -31,7 +31,7 @@ namespace Umbraco.Core.Models set { _preValuesAsArray = value; } } - public IDictionary PreValuesAsDictionary + public IDictionary PreValuesAsDictionary { get { @@ -57,12 +57,12 @@ namespace Umbraco.Core.Models _preValuesAsArray = preVals; } - public PreValueCollection(IDictionary preVals) + public PreValueCollection(IDictionary preVals) { _preValuesAsDictionary = preVals; } - internal static IDictionary AsDictionary(PreValueCollection persistedPreVals) + internal static IDictionary AsDictionary(PreValueCollection persistedPreVals) { if (persistedPreVals.IsDictionaryBased) { @@ -70,7 +70,7 @@ namespace Umbraco.Core.Models } //it's an array so need to format it - var result = new Dictionary(); + var result = new Dictionary(); var asArray = persistedPreVals.PreValuesAsArray.ToArray(); for (var i = 0; i < asArray.Length; i++) { diff --git a/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs b/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs index be006a71d7..deb38d1201 100644 --- a/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using Umbraco.Core.Models; namespace Umbraco.Core.PropertyEditors { @@ -29,5 +30,67 @@ namespace Umbraco.Core.PropertyEditors [JsonProperty("fields")] public IEnumerable Fields { get; set; } + /// + /// A method to format the posted values from the editor to the values to be persisted + /// + /// + /// + /// The current value that has been persisted to the database for this pre-value editor. This value may be usesful for + /// how the value then get's deserialized again to be re-persisted. In most cases it will probably not be used. + /// + /// + /// + /// By default this will just return the Posted editorValue. + /// + /// This can be overridden if perhaps you have a comma delimited string posted value but want to convert those to individual rows, or to convert + /// a json structure to multiple rows. + /// + public virtual IDictionary FormatDataForPersistence(IDictionary editorValue, PreValueCollection currentValue) + { + return editorValue; + } + + /// + /// This can be used to re-format the currently saved pre-values that will be passed to the editor, + /// by default this returns the merged default and persisted pre-values. + /// + /// + /// The default/static pre-vals for the property editor + /// + /// + /// The persisted pre-vals for the property editor + /// + /// + /// + /// This is generally not going to be used by anything unless a property editor wants to change the merging + /// functionality or needs to convert some legacy persisted data, or convert the string values to strongly typed values in json (i.e. booleans) + /// + public virtual IDictionary FormatDataForEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals) + { + if (defaultPreVals == null) + { + defaultPreVals = new Dictionary(); + } + + if (persistedPreVals.IsDictionaryBased) + { + //we just need to merge the dictionaries now, the persisted will replace default. + foreach (var item in persistedPreVals.PreValuesAsDictionary) + { + defaultPreVals[item.Key] = item.Value; + } + return defaultPreVals; + } + + //it's an array so need to format it + var result = new Dictionary(); + var asArray = persistedPreVals.PreValuesAsArray.ToArray(); + for (var i = 0; i < asArray.Length; i++) + { + result.Add(i.ToInvariantString(), asArray[i]); + } + return result; + } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/PropertyEditors/PreValueField.cs b/src/Umbraco.Core/PropertyEditors/PreValueField.cs index 94309e2ec7..8e161df81c 100644 --- a/src/Umbraco.Core/PropertyEditors/PreValueField.cs +++ b/src/Umbraco.Core/PropertyEditors/PreValueField.cs @@ -8,6 +8,11 @@ namespace Umbraco.Core.PropertyEditors /// public class PreValueField { + public PreValueField() + { + Validators = new List(); + } + /// /// The name to display for this pre-value field /// diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditor.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditor.cs index ae71b5c7a6..b40b6e451c 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditor.cs @@ -112,49 +112,7 @@ namespace Umbraco.Core.PropertyEditors } return StaticallyDefinedPreValueEditor; } - - /// - /// This can be used to re-format the currently saved pre-values that will be passed to the editor, - /// by default this returns the merged default and persisted pre-values. - /// - /// - /// The default/static pre-vals for the property editor - /// - /// - /// The persisted pre-vals for the property editor - /// - /// - /// - /// This is generally not going to be used by anything unless a property editor wants to change the merging - /// functionality or needs to convert some legacy persisted data, or convert the string values to strongly typed values in json (i.e. booleans) - /// - public virtual IDictionary FormatPreValues(IDictionary defaultPreVals, PreValueCollection persistedPreVals) - { - if (defaultPreVals == null) - { - defaultPreVals = new Dictionary(); - } - - if (persistedPreVals.IsDictionaryBased) - { - //we just need to merge the dictionaries now, the persisted will replace default. - foreach (var item in persistedPreVals.PreValuesAsDictionary) - { - defaultPreVals[item.Key] = item.Value; - } - return defaultPreVals; - } - - //it's an array so need to format it - var result = new Dictionary(); - var asArray = persistedPreVals.PreValuesAsArray.ToArray(); - for (var i = 0; i < asArray.Length; i++) - { - result.Add(i.ToInvariantString(), asArray[i]); - } - return result; - } - + protected bool Equals(PropertyEditor other) { return Id.Equals(other.Id); diff --git a/src/Umbraco.Core/PropertyEditors/ValueEditor.cs b/src/Umbraco.Core/PropertyEditors/ValueEditor.cs index 1b5b0e7118..637bffbc4a 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueEditor.cs @@ -161,7 +161,7 @@ namespace Umbraco.Core.PropertyEditors /// If overridden then the object returned must match the type supplied in the ValueType, otherwise persisting the /// value to the DB will fail when it tries to validate the value type. /// - public virtual object DeserializeValue(ContentPropertyData editorValue, object currentValue) + public virtual object FormatDataForPersistence(ContentPropertyData editorValue, object currentValue) { var result = TryConvertValueToCrlType(editorValue.Value); if (result.Success == false) @@ -177,7 +177,7 @@ namespace Umbraco.Core.PropertyEditors /// /// /// - public virtual string SerializeValue(object dbValue) + public virtual string FormatDataForEditor(object dbValue) { if (dbValue == null) return string.Empty; diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index e5a7002037..abfb4255c7 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -443,7 +443,7 @@ namespace Umbraco.Core.Services internal static PreValueCollection ConvertToPreValuesCollection(IEnumerable> list) { //now we need to determine if they are dictionary based, otherwise they have to be array based - var dictionary = new Dictionary(); + var dictionary = new Dictionary(); //need to check all of the keys, if there's only one and it is empty then it's an array var keys = list.Select(x => x.Item2).Distinct().ToArray(); diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs index 730dd4ad56..1a0104a9af 100644 --- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueEditorTests.cs @@ -52,7 +52,7 @@ namespace Umbraco.Tests.PropertyEditors ValueType = valueType }; - var result = valueEditor.SerializeValue(val); + var result = valueEditor.FormatDataForEditor(val); Assert.AreEqual(expected, result); } @@ -65,7 +65,7 @@ namespace Umbraco.Tests.PropertyEditors ValueType = "DATE" }; - var result = valueEditor.SerializeValue(now); + var result = valueEditor.FormatDataForEditor(now); Assert.AreEqual(now.ToXmlString(), result); } } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js index 89e23b5e31..049d27ee1a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js @@ -7,14 +7,18 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) { return { - getPreValues: function (editorId) { + getPreValues: function (editorId, dataTypeId) { + + if (!dataTypeId) { + dataTypeId = -1; + } return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( "dataTypeApiBaseUrl", "GetPreValues", - [{ editorId: editorId }])), + [{ editorId: editorId }, { dataTypeId: dataTypeId }])), 'Failed to retreive pre values for editor id ' + editorId); }, diff --git a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js index 40f91b7b03..fe70aefa44 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js @@ -69,7 +69,8 @@ function DataTypeEditController($scope, $routeParams, $location, dataTypeResourc //when the value changes, we need to dynamically load in the new editor if (newVal !== null && newVal !== undefined && newVal != oldVal) { //we are editing so get the content item from the server - dataTypeResource.getPreValues(newVal) + var currDataTypeId = $routeParams.create ? undefined : $routeParams.id; + dataTypeResource.getPreValues(newVal, currDataTypeId) .then(function (data) { $scope.preValuesLoaded = true; $scope.content.preValues = data; 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 e67d96f0a1..eeebe1d3cf 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 @@ -1,4 +1,5 @@
- Hello world + I will finish this tomorrow. +
\ No newline at end of file diff --git a/src/Umbraco.Web/Editors/ContentControllerBase.cs b/src/Umbraco.Web/Editors/ContentControllerBase.cs index 967031a399..d40dfeb9fd 100644 --- a/src/Umbraco.Web/Editors/ContentControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentControllerBase.cs @@ -107,7 +107,7 @@ namespace Umbraco.Web.Editors //don't persist any bound value if the editor is readonly if (valueEditor.IsReadOnly == false) { - dboProperty.Value = p.PropertyEditor.ValueEditor.DeserializeValue(data, dboProperty.Value); + dboProperty.Value = p.PropertyEditor.ValueEditor.FormatDataForPersistence(data, dboProperty.Value); } } diff --git a/src/Umbraco.Web/Editors/DataTypeController.cs b/src/Umbraco.Web/Editors/DataTypeController.cs index f84fd9b48a..3246f8b86a 100644 --- a/src/Umbraco.Web/Editors/DataTypeController.cs +++ b/src/Umbraco.Web/Editors/DataTypeController.cs @@ -5,6 +5,7 @@ using System.Net; using System.Web.Http; using System.Web.Http.ModelBinding; using AutoMapper; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; @@ -54,8 +55,9 @@ namespace Umbraco.Web.Editors /// Returns the pre-values for the specified property editor /// /// + /// The data type id for the pre-values, -1 if it is a new data type /// - public IEnumerable GetPreValues(Guid editorId) + public IEnumerable GetPreValues(Guid editorId, int dataTypeId = -1) { var propEd = PropertyEditorResolver.Current.GetById(editorId); if (propEd == null) @@ -63,6 +65,29 @@ namespace Umbraco.Web.Editors throw new InvalidOperationException("Could not find property editor with id " + editorId); } + if (dataTypeId == -1) + { + //this is a new data type, so just return the field editors, there are no values yet + return propEd.PreValueEditor.Fields.Select(Mapper.Map); + } + + //we have a data type associated + var dataType = Services.DataTypeService.GetDataTypeDefinitionById(dataTypeId); + if (dataType == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + + //now, lets check if the data type has the current editor selected, if that is true + //we will need to wire up it's saved values. Otherwise it's an existing data type + //that is changing it's underlying property editor, in which case there's no values. + if (dataType.ControlId == editorId) + { + //this is the currently assigned pre-value editor, return with values. + return Mapper.Map>(dataType); + } + + //return the pre value display without values return propEd.PreValueEditor.Fields.Select(Mapper.Map); } @@ -80,7 +105,23 @@ namespace Umbraco.Web.Editors //finally we need to save the data type and it's pre-vals var dtService = (DataTypeService) ApplicationContext.Services.DataTypeService; - var preVals = Mapper.Map(dataType.PreValues); + + //TODO: Check if the property editor has changed, if it has ensure we don't pass the + // existing values to the new property editor! + + //get the prevalues, current and new + var preValDictionary = dataType.PreValues.ToDictionary(x => x.Key, x => x.Value); + var currVal = ((DataTypeService) Services.DataTypeService).GetPreValuesCollectionByDataTypeId(dataType.PersistedDataType.Id); + + //we need to allow for the property editor to deserialize the prevalues + var formattedVal = dataType.PropertyEditor.PreValueEditor.FormatDataForPersistence( + preValDictionary, + currVal); + + //create the pre-value collection to be saved + var preVals = new PreValueCollection(formattedVal.ToDictionary(x => x.Key, x => x.Value)); + + //save the data type dtService.SaveDataTypeAndPreValues(dataType.PersistedDataType, preVals, (int)Security.CurrentUser.Id); var display = Mapper.Map(dataType.PersistedDataType); diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs index 32313cf75e..a68d7fa29d 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs @@ -42,7 +42,7 @@ namespace Umbraco.Web.Models.Mapping var result = new T { Id = property.Id, - Value = editor.ValueEditor.SerializeValue(property.Value), + Value = editor.ValueEditor.FormatDataForEditor(property.Value), Alias = property.Alias }; diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs index 1eb883e1eb..5daab4427f 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs @@ -9,7 +9,7 @@ using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { /// - /// Creates a ContentPropertyDto from a Property + /// Creates a ContentPropertyDisplay from a Property /// internal class ContentPropertyDisplayConverter : ContentPropertyBasicConverter { @@ -35,16 +35,15 @@ namespace Umbraco.Web.Models.Mapping if (display.PropertyEditor == null) { - display.Config = PreValueCollection.AsDictionary(preVals); + //display.Config = PreValueCollection.AsDictionary(preVals); //if there is no property editor it means that it is a legacy data type // we cannot support editing with that so we'll just render the readonly value view. - display.View = GlobalSettings.Path.EnsureEndsWith('/') + - "views/propertyeditors/readonlyvalue/readonlyvalue.html"; + display.View = "views/propertyeditors/readonlyvalue/readonlyvalue.html"; } else { //let the property editor format the pre-values - display.Config = display.PropertyEditor.FormatPreValues(display.PropertyEditor.DefaultPreValues, preVals); + display.Config = display.PropertyEditor.PreValueEditor.FormatDataForEditor(display.PropertyEditor.DefaultPreValues, preVals); display.View = display.PropertyEditor.ValueEditor.View; } diff --git a/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs index 0f4a53f9e2..8b5521ba10 100644 --- a/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/DataTypeModelMapper.cs @@ -24,6 +24,7 @@ namespace Umbraco.Web.Models.Mapping config.CreateMap() .ForMember(basic => basic.EditorId, expression => expression.MapFrom(editor => editor.Id)); + //just maps the standard properties, does not map the value! config.CreateMap(); config.CreateMap() @@ -33,15 +34,20 @@ namespace Umbraco.Web.Models.Mapping .ForMember(display => display.SelectedEditor, expression => expression.MapFrom( definition => definition.ControlId == Guid.Empty ? null : (Guid?) definition.ControlId)); + //gets a list of PreValueFieldDisplay objects from the data type definition + config.CreateMap>() + .ConvertUsing(definition => + { + var resolver = new PreValueDisplayResolver(lazyDataTypeService); + return resolver.Convert(definition); + }); + + config.CreateMap() .ConstructUsing(save => new DataTypeDefinition(-1, save.SelectedEditor) {CreateDate = DateTime.Now}) .ForMember(definition => definition.ControlId, expression => expression.MapFrom(save => save.SelectedEditor)) .ForMember(definition => definition.ParentId, expression => expression.MapFrom(save => -1)) .ForMember(definition => definition.DatabaseType, expression => expression.ResolveUsing()); - - config.CreateMap, PreValueCollection>() - .ConstructUsing( - saves => new PreValueCollection(saves.ToDictionary(x => x.Key, x => (object) x.Value))); } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/PreValueDisplayResolver.cs b/src/Umbraco.Web/Models/Mapping/PreValueDisplayResolver.cs index f89047a83d..3457d2e781 100644 --- a/src/Umbraco.Web/Models/Mapping/PreValueDisplayResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/PreValueDisplayResolver.cs @@ -20,7 +20,7 @@ namespace Umbraco.Web.Models.Mapping _dataTypeService = dataTypeService; } - protected override IEnumerable ResolveCore(IDataTypeDefinition source) + internal IEnumerable Convert(IDataTypeDefinition source) { PropertyEditor propEd = null; if (source.ControlId != Guid.Empty) @@ -29,20 +29,25 @@ namespace Umbraco.Web.Models.Mapping if (propEd == null) { throw new InvalidOperationException("Could not find property editor with id " + source.ControlId); - } + } } - - var dataTypeService = (DataTypeService) _dataTypeService.Value; + //set up the defaults + var dataTypeService = (DataTypeService)_dataTypeService.Value; var preVals = dataTypeService.GetPreValuesCollectionByDataTypeId(source.Id); - var dictionaryVals = PreValueCollection.AsDictionary(preVals); + IDictionary dictionaryVals = PreValueCollection.AsDictionary(preVals).ToDictionary(x => x.Key, x => (object)x.Value); + var result = Enumerable.Empty().ToArray(); - var result = Enumerable.Empty(); + //if we have a prop editor, then format the pre-values based on it and create it's fields. if (propEd != null) { - result = propEd.PreValueEditor.Fields.Select(Mapper.Map).ToArray(); + result = propEd.PreValueEditor.Fields.Select(Mapper.Map).ToArray(); + dictionaryVals = propEd.PreValueEditor.FormatDataForEditor(propEd.DefaultPreValues, preVals); } + var currentIndex = 0; //used if the collection is non-dictionary based. + + //now we need to wire up the pre-values values with the actual fields defined foreach (var field in result) { if (preVals.IsDictionaryBased == false) @@ -54,7 +59,7 @@ namespace Umbraco.Web.Models.Mapping LogHelper.Warn("Could not find persisted pre-value for index " + currentIndex); continue; } - field.Value = (string) dictionaryVals.Single(x => x.Key.InvariantEquals(currentIndex.ToInvariantString())).Value; + field.Value = dictionaryVals.Single(x => x.Key.InvariantEquals(currentIndex.ToInvariantString())).Value.ToString(); currentIndex++; } else @@ -65,13 +70,18 @@ namespace Umbraco.Web.Models.Mapping LogHelper.Warn("Could not find persisted pre-value for field " + field.Key); continue; } - field.Value = (string)dictionaryVals.Single(x => x.Key.InvariantEquals(field.Key)).Value; + field.Value = dictionaryVals.Single(x => x.Key.InvariantEquals(field.Key)).Value.ToString(); } - + } return result; } + + protected override IEnumerable ResolveCore(IDataTypeDefinition source) + { + return Convert(source); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs index 20831fadfc..324b9d6b4c 100644 --- a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs @@ -5,36 +5,9 @@ using Newtonsoft.Json.Linq; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; -using umbraco; namespace Umbraco.Web.PropertyEditors { - [PropertyEditor(Constants.PropertyEditors.DropDownList, "Dropdown list", "dropdown")] - public class DropDownPropertyEditor : PropertyEditor - { - protected override PreValueEditor CreatePreValueEditor() - { - var editor = base.CreatePreValueEditor(); - - editor.Fields = new List - { - new PreValueField - { - Description = "Add and remove values for the drop down list", - //we're going to call this 'temp' because we are going to override the - //serialization of the pre-values to ensure that each one gets saved with it's own key - //(new db row per pre-value, thus to maintain backwards compatibility) - Key = "temp", - Name = ui.Text("editdatatype", "addPrevalue"), - View = "Views/PropertyEditors/dropdown/dropdown.prevalue.html" - } - }; - - return editor; - } - } - - [PropertyEditor(Constants.PropertyEditors.Date, "Date", "DATE", "datepicker")] public class DatePropertyEditor : PropertyEditor { @@ -79,7 +52,7 @@ namespace Umbraco.Web.PropertyEditors Validators = new List { new DateTimeValidator() }; } - public override string SerializeValue(object dbValue) + public override string FormatDataForEditor(object dbValue) { var date = dbValue.TryConvertTo(); if (date.Success == false || date.Result == null) diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs new file mode 100644 index 0000000000..a06157c5da --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; + +namespace Umbraco.Web.PropertyEditors +{ + internal class DropDownPreValueEditor : PreValueEditor + { + /// + /// The editor is expecting a json array for a field with a key named "temp" so we need to format the persisted values + /// to this format to be used in the editor. + /// + /// + /// + /// + public override IDictionary FormatDataForEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals) + { + var dictionary = PreValueCollection.AsDictionary(persistedPreVals); + var arrayOfVals = dictionary.Select(item => item.Value).ToList(); + var json = JsonConvert.SerializeObject(arrayOfVals); + + return new Dictionary {{"temp", json}}; + } + + /// + /// Need to format the delimited posted string to individual values + /// + /// + /// + /// + /// + /// This is mostly because we want to maintain compatibility with v6 drop down property editors that store their prevalues in different db rows. + /// + public override IDictionary FormatDataForPersistence(IDictionary editorValue, Core.Models.PreValueCollection currentValue) + { + var val = editorValue["temp"]; + var result = new Dictionary(); + if (val.IsNullOrWhiteSpace()) return result; + + try + { + var deserialized = JsonConvert.DeserializeObject(val); + var index = 0; + foreach (var item in deserialized) + { + result.Add(index.ToInvariantString(), item); + index++; + } + } + catch (Exception ex) + { + LogHelper.Error("Could not deserialize the posted value: " + val, ex); + } + + return result; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs new file mode 100644 index 0000000000..f668dcd9cf --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Umbraco.Core; +using Umbraco.Core.PropertyEditors; +using umbraco; + +namespace Umbraco.Web.PropertyEditors +{ + [PropertyEditor(Constants.PropertyEditors.DropDownList, "Dropdown list", "dropdown")] + public class DropDownPropertyEditor : PropertyEditor + { + protected override PreValueEditor CreatePreValueEditor() + { + var editor = new DropDownPreValueEditor + { + Fields = new List + { + new PreValueField + { + Description = "Add and remove values for the drop down list", + //we're going to call this 'temp' because we are going to override the + //serialization of the pre-values to ensure that each one gets saved with it's own key + //(new db row per pre-value, thus to maintain backwards compatibility) + Key = "temp", + Name = ui.Text("editdatatype", "addPrevalue"), + View = "Views/PropertyEditors/dropdown/dropdown.prevalue.html" + } + } + }; + + return editor; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadValueEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadValueEditor.cs index 078ddeb302..af20c14f3a 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadValueEditor.cs @@ -39,7 +39,7 @@ namespace Umbraco.Web.PropertyEditors /// file path or use the existing file path. /// /// - public override object DeserializeValue(ContentPropertyData editorValue, object currentValue) + public override object FormatDataForPersistence(ContentPropertyData editorValue, object currentValue) { if (currentValue == null) { diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 1b693ca062..57c102db95 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -317,6 +317,8 @@ + +