diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs
new file mode 100644
index 0000000000..4292caf59d
--- /dev/null
+++ b/src/Umbraco.Core/Models/PreValue.cs
@@ -0,0 +1,25 @@
+namespace Umbraco.Core.Models
+{
+ ///
+ /// Represents a stored pre-value field value
+ ///
+ public class PreValue
+ {
+ public PreValue(int id, string value)
+ {
+ Value = value;
+ Id = id;
+
+ }
+
+ ///
+ /// The value stored for the pre-value field
+ ///
+ public string Value { get; private set; }
+
+ ///
+ /// The database id for the pre-value field value
+ ///
+ public int Id { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/PreValueCollection.cs b/src/Umbraco.Core/Models/PreValueCollection.cs
index 9741869a50..5e27e69594 100644
--- a/src/Umbraco.Core/Models/PreValueCollection.cs
+++ b/src/Umbraco.Core/Models/PreValueCollection.cs
@@ -16,9 +16,9 @@ namespace Umbraco.Core.Models
///
public class PreValueCollection
{
- private IDictionary _preValuesAsDictionary;
- private IEnumerable _preValuesAsArray;
- public IEnumerable PreValuesAsArray
+ private IDictionary _preValuesAsDictionary;
+ private IEnumerable _preValuesAsArray;
+ public IEnumerable PreValuesAsArray
{
get
{
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Models
set { _preValuesAsArray = value; }
}
- public IDictionary PreValuesAsDictionary
+ public IDictionary PreValuesAsDictionary
{
get
{
@@ -52,25 +52,25 @@ namespace Umbraco.Core.Models
get { return _preValuesAsDictionary != null; }
}
- public PreValueCollection(IEnumerable preVals)
+ public PreValueCollection(IEnumerable preVals)
{
_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)
{
return persistedPreVals.PreValuesAsDictionary;
}
- //it's an array so need to format it
- var result = new Dictionary();
+ //it's an array so need to format it, the alias will just be an iteration
+ var result = new Dictionary();
var asArray = persistedPreVals.PreValuesAsArray.ToArray();
for (var i = 0; i < asArray.Length; i++)
{
diff --git a/src/Umbraco.Core/Models/PropertyExtensions.cs b/src/Umbraco.Core/Models/PropertyExtensions.cs
index 5e3328de56..8edf32bb41 100644
--- a/src/Umbraco.Core/Models/PropertyExtensions.cs
+++ b/src/Umbraco.Core/Models/PropertyExtensions.cs
@@ -44,37 +44,19 @@ namespace Umbraco.Core.Models
var propertyEditor = PropertyEditorResolver.Current.GetById(property.PropertyType.DataTypeId);
if (propertyEditor != null)
{
+ var cacheValue = propertyEditor.ValueEditor.FormatValueForCache(property);
+
switch (property.PropertyType.DataTypeDatabaseType)
{
- case DataTypeDatabaseType.Nvarchar:
- xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString()));
- break;
+ case DataTypeDatabaseType.Nvarchar:
+ case DataTypeDatabaseType.Date:
case DataTypeDatabaseType.Integer:
- xmlNode.AppendChild(xd.CreateTextNode(property.Value.ToXmlString(property.Value.GetType())));
+ xmlNode.AppendChild(xd.CreateTextNode(cacheValue.ToString()));
break;
case DataTypeDatabaseType.Ntext:
//put text in cdata
- xmlNode.AppendChild(xd.CreateCDataSection(property.Value.ToXmlString()));
- break;
- case DataTypeDatabaseType.Date:
- //treat dates differently, output the format as xml format
- if (property.Value == null)
- {
- xmlNode.AppendChild(xd.CreateTextNode(string.Empty));
- }
- else
- {
- var date = property.Value.TryConvertTo();
- if (date.Success == false || date.Result == null)
- {
- xmlNode.AppendChild(xd.CreateTextNode(string.Empty));
- }
- else
- {
- xmlNode.AppendChild(xd.CreateTextNode(date.Result.ToXmlString()));
- }
- }
- break;
+ xmlNode.AppendChild(xd.CreateCDataSection(cacheValue.ToString()));
+ break;
default:
throw new ArgumentOutOfRangeException();
}
diff --git a/src/Umbraco.Core/PropertyEditors/ValueEditor.cs b/src/Umbraco.Core/PropertyEditors/ValueEditor.cs
index ef4b711b66..aba131ab9b 100644
--- a/src/Umbraco.Core/PropertyEditors/ValueEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/ValueEditor.cs
@@ -202,5 +202,42 @@ namespace Umbraco.Core.PropertyEditors
throw new ArgumentOutOfRangeException();
}
}
+
+ ///
+ /// Converts the property value for use in the front-end cache
+ ///
+ ///
+ ///
+ public virtual object FormatValueForCache(Property property)
+ {
+ if (property.Value == null)
+ {
+ return string.Empty;
+ }
+
+ switch (GetDatabaseType())
+ {
+ case DataTypeDatabaseType.Nvarchar:
+ case DataTypeDatabaseType.Ntext:
+ property.Value.ToXmlString();
+ return property.Value.ToXmlString();
+ case DataTypeDatabaseType.Integer:
+ return property.Value.ToXmlString(property.Value.GetType());
+ case DataTypeDatabaseType.Date:
+ //treat dates differently, output the format as xml format
+ if (property.Value == null)
+ {
+ return string.Empty;
+ }
+ var date = property.Value.TryConvertTo();
+ if (date.Success == false || date.Result == null)
+ {
+ return string.Empty;
+ }
+ return date.Result.ToXmlString();
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs
index abfb4255c7..9d0c9a493b 100644
--- a/src/Umbraco.Core/Services/DataTypeService.cs
+++ b/src/Umbraco.Core/Services/DataTypeService.cs
@@ -143,7 +143,7 @@ namespace Umbraco.Core.Services
using (var uow = _uowProvider.GetUnitOfWork())
{
var dtos = uow.Database.Fetch("WHERE datatypeNodeId = @Id", new { Id = id });
- var list = dtos.Select(x => new Tuple(x.Id, x.Alias, x.SortOrder, x.Value)).ToList();
+ var list = dtos.Select(x => new Tuple(new PreValue(x.Id, x.Value), x.Alias, x.SortOrder)).ToList();
return PreValueConverter.ConvertToPreValuesCollection(list);
}
@@ -262,7 +262,7 @@ namespace Umbraco.Core.Services
///
/// We will actually just remove all pre-values and re-insert them in one transaction
///
- internal void SavePreValues(int id, PreValueCollection values)
+ internal void SavePreValues(int id, IDictionary values)
{
//TODO: Should we raise an event here since we are really saving values for the data type?
@@ -275,12 +275,12 @@ namespace Umbraco.Core.Services
uow.Database.Execute("DELETE FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
var sortOrder = 1;
- foreach (var value in PreValueCollection.AsDictionary(values))
+ foreach (var value in values)
{
var dto = new DataTypePreValueDto
{
DataTypeNodeId = id,
- Value = (string)value.Value,
+ Value = value.Value,
SortOrder = sortOrder,
Alias = value.Key
};
@@ -300,7 +300,7 @@ namespace Umbraco.Core.Services
///
///
///
- internal void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, PreValueCollection values, int userId = 0)
+ internal void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, IDictionary values, int userId = 0)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs(dataTypeDefinition), this))
return;
@@ -320,12 +320,12 @@ namespace Umbraco.Core.Services
database.Execute("DELETE FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = dataTypeDefinition.Id });
var sortOrder = 1;
- foreach (var value in PreValueCollection.AsDictionary(values))
+ foreach (var value in values)
{
var dto = new DataTypePreValueDto
{
DataTypeNodeId = dataTypeDefinition.Id,
- Value = (string)value.Value,
+ Value = value.Value,
SortOrder = sortOrder,
Alias = value.Key
};
@@ -440,29 +440,29 @@ namespace Umbraco.Core.Services
///
///
///
- internal static PreValueCollection ConvertToPreValuesCollection(IEnumerable> list)
+ 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();
if (keys.Length == 1 && keys[0].IsNullOrWhiteSpace())
{
- return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item4));
+ return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item1));
}
foreach (var item in list
.OrderBy(x => x.Item3) //we'll order them first so we maintain the order index in the dictionary
- .GroupBy(x => x.Item2))
+ .GroupBy(x => x.Item2)) //group by alias
{
if (item.Count() > 1)
{
//if there's more than 1 item per key, then it cannot be a dictionary, just return the array
- return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item4));
+ return new PreValueCollection(list.OrderBy(x => x.Item3).Select(x => x.Item1));
}
- dictionary.Add(item.Key, item.First().Item4);
+ dictionary.Add(item.Key, item.First().Item1);
}
return new PreValueCollection(dictionary);
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index ba2e662304..47365e2ea1 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -225,6 +225,7 @@
+
diff --git a/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs
new file mode 100644
index 0000000000..833417865c
--- /dev/null
+++ b/src/Umbraco.Tests/PropertyEditors/DropDownPropertyPreValueEditorTests.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using NUnit.Framework;
+using Umbraco.Core.Models;
+using Umbraco.Web.PropertyEditors;
+
+namespace Umbraco.Tests.PropertyEditors
+{
+ [TestFixture]
+ public class DropDownPropertyPreValueEditorTests
+ {
+ [Test]
+ public void Format_Data_For_Editor()
+ {
+
+ var defaultVals = new Dictionary();
+ var persisted = new PreValueCollection(new Dictionary
+ {
+ {"item1", new PreValue(1, "Item 1")},
+ {"item2", new PreValue(2, "Item 2")},
+ {"item3", new PreValue(3, "Item 3")}
+ });
+
+ var editor = new DropDownPreValueEditor();
+
+ var result = editor.FormatDataForEditor(defaultVals, persisted);
+
+ Assert.AreEqual(1, result.Count);
+ Assert.IsTrue(result.ContainsKey("items"));
+ var items = result["items"] as IDictionary;
+ Assert.IsNotNull(items);
+ Assert.AreEqual("Item 1", items[1]);
+ Assert.AreEqual("Item 2", items[2]);
+ Assert.AreEqual("Item 3", items[3]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
index 989895f50d..c151ccc7a8 100644
--- a/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
+++ b/src/Umbraco.Tests/PropertyEditors/PropertyEditorValueConverterTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using NUnit.Framework;
using Umbraco.Core.PropertyEditors;
using Umbraco.Tests.TestHelpers;
diff --git a/src/Umbraco.Tests/Services/PreValueConverterTests.cs b/src/Umbraco.Tests/Services/PreValueConverterTests.cs
index d02544052b..7a326b7fd9 100644
--- a/src/Umbraco.Tests/Services/PreValueConverterTests.cs
+++ b/src/Umbraco.Tests/Services/PreValueConverterTests.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
+using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Umbraco.Tests.Services
@@ -12,12 +13,12 @@ namespace Umbraco.Tests.Services
[Test]
public void Can_Convert_To_Dictionary_Pre_Value_Collection()
{
- var list = new List>
+ var list = new List>
{
- new Tuple(10, "key1", 0, "value1"),
- new Tuple(11, "key2", 3, "value2"),
- new Tuple(12, "key3", 2, "value3"),
- new Tuple(13, "key4", 1, "value4")
+ new Tuple(new PreValue(10, "value1"), "key1", 0),
+ new Tuple(new PreValue(11, "value2"), "key2", 3),
+ new Tuple(new PreValue(12, "value3"), "key3", 2),
+ new Tuple(new PreValue(13, "value4"), "key4", 1)
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
@@ -38,12 +39,12 @@ namespace Umbraco.Tests.Services
[Test]
public void Can_Convert_To_Array_Pre_Value_Collection_When_Empty_Key()
{
- var list = new List>
+ var list = new List>
{
- new Tuple(10, "", 0, "value1"),
- new Tuple(11, "", 3, "value2"),
- new Tuple(12, "", 2, "value3"),
- new Tuple(13, "", 1, "value4")
+ new Tuple(new PreValue(10, "value1"), "", 0),
+ new Tuple(new PreValue(11, "value2"), "", 3),
+ new Tuple(new PreValue(12, "value3"), "", 2),
+ new Tuple(new PreValue(13, "value4"), "", 1)
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
@@ -54,22 +55,22 @@ namespace Umbraco.Tests.Services
});
Assert.AreEqual(4, result.PreValuesAsArray.Count());
- Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0));
- Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1));
- Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2));
- Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3));
+ Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0).Value);
+ Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1).Value);
+ Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2).Value);
+ Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3).Value);
}
[Test]
public void Can_Convert_To_Array_Pre_Value_Collection()
{
- var list = new List>
+ var list = new List>
{
- new Tuple(10, "key1", 0, "value1"),
- new Tuple(11, "key1", 3, "value2"),
- new Tuple(12, "key3", 2, "value3"),
- new Tuple(13, "key4", 1, "value4")
+ new Tuple(new PreValue(10, "value1"), "key1", 0),
+ new Tuple(new PreValue(11, "value2"), "key1", 3),
+ new Tuple(new PreValue(12, "value3"), "key3", 2),
+ new Tuple(new PreValue(13, "value4"), "key4", 1)
};
var result = DataTypeService.PreValueConverter.ConvertToPreValuesCollection(list);
@@ -80,10 +81,10 @@ namespace Umbraco.Tests.Services
});
Assert.AreEqual(4, result.PreValuesAsArray.Count());
- Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0));
- Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1));
- Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2));
- Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3));
+ Assert.AreEqual("value1", result.PreValuesAsArray.ElementAt(0).Value);
+ Assert.AreEqual("value4", result.PreValuesAsArray.ElementAt(1).Value);
+ Assert.AreEqual("value3", result.PreValuesAsArray.ElementAt(2).Value);
+ Assert.AreEqual("value2", result.PreValuesAsArray.ElementAt(3).Value);
}
}
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index a05aeee774..2fedf23c7e 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -213,6 +213,7 @@
+
diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js
index 675203cd0e..d5f9e264ff 100644
--- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js
+++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/_utils.js
@@ -24,13 +24,13 @@ angular.module('umbraco.mocks').
{
label: "Custom pre value 1 for editor " + selectedId,
description: "Enter a value for this pre-value",
- key: "myPreVal",
+ key: "myPreVal1",
view: "requiredfield"
},
{
label: "Custom pre value 2 for editor " + selectedId,
description: "Enter a value for this pre-value",
- key: "myPreVal",
+ key: "myPreVal2",
view: "requiredfield"
}
]
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 c709cfe232..8af17a18ea 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/boolean.html
@@ -1,3 +1 @@
-
-
-{{model | json}}
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/hidden.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/hidden.html
new file mode 100644
index 0000000000..758ba68fd7
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/hidden.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/requiredfield.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/requiredfield.html
index 14c06d29d6..2d1f3dde42 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/requiredfield.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/requiredfield.html
@@ -1,9 +1,9 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textarea.html b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textarea.html
index e6c0177924..2321f3dd8d 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textarea.html
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/textarea.html
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js
index ce75a5ab04..483f1ef5cd 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.controller.js
@@ -4,9 +4,7 @@ angular.module("umbraco").controller("Umbraco.Editors.DropdownController",
//setup the default config
var config = {
items: [],
- multiple: false,
- keyName: "alias",
- valueName: "name"
+ multiple: false
};
//map the user config
@@ -14,25 +12,16 @@ angular.module("umbraco").controller("Umbraco.Editors.DropdownController",
//map back to the model
$scope.model.config = config;
- $scope.selectExpression = "e." + config.keyName + " as e." + config.valueName + " for e in model.config.items";
-
- //now we need to format the items in the array because we always want to have a dictionary
- for (var i = 0; i < $scope.model.config.items.length; i++) {
- if (angular.isString($scope.model.config.items[i])) {
- //convert to key/value
- var keyVal = {};
- keyVal[$scope.model.config.keyName] = $scope.model.config.items[i];
- keyVal[$scope.model.config.valueName] = $scope.model.config.items[i];
- $scope.model.config.items[i] = keyVal;
- }
- else if (angular.isObject($scope.model.config.items[i])) {
- if ($scope.model.config.items[i][$scope.model.config.keyName] === undefined || $scope.model.config.items[i][$scope.model.config.valueName] === undefined) {
- throw "All objects in the items array must have a key with a name " + $scope.model.config.keyName + " and a value with a name " + $scope.model.config.valueName;
- }
- }
- else {
- throw "The items array must contain either a key value pair or a string";
+ if (angular.isArray($scope.model.config.items)) {
+ //now we need to format the items in the array because we always want to have a dictionary
+ var newItems = {};
+ for (var i = 0; i < $scope.model.config.items.length; i++) {
+ newItems[$scope.model.config.items[i]] = $scope.model.config.items[i];
}
+ $scope.model.config.items = newItems;
+ }
+ else if (!angular.isObject($scope.model.config.items)) {
+ throw "The items property must be either an array or a dictionary";
}
//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
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html
index a4e7079c1b..f27183c052 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/dropdown/dropdown.html
@@ -1,6 +1,19 @@
-
+
+
+ ng-switch-default
+ ng-model="model.value"
+ ng-options="key as val for (key, val) in model.config.items">
+
+
+
+
+
-
\ No newline at end of file
+
+{{model.value | json}}
\ No newline at end of file
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 6f10385cfb..2d3d208a35 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
@@ -3,14 +3,31 @@ angular.module("umbraco").controller("Umbraco.Editors.DropdownPreValueController
$scope.newItem = "";
$scope.hasError = false;
+
+ if (!angular.isArray($scope.model.value)) {
+ //make an array from the dictionary
+ var items = [];
+ for (var i in $scope.model.value) {
+ items.push($scope.model.value[i]);
+ }
+ //now make the editor model the array
+ $scope.model.value = items;
+ }
$scope.remove = function(item, evt) {
evt.preventDefault();
- $scope.model.value = _.reject($scope.model.value, function(i) {
+ $scope.model.value = _.reject($scope.model.value, function (i) {
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/test/unit/app/propertyeditors/dropdown-controller.spec.js b/src/Umbraco.Web.UI.Client/test/unit/app/propertyeditors/dropdown-controller.spec.js
index 017571354a..e12d3686c7 100644
--- a/src/Umbraco.Web.UI.Client/test/unit/app/propertyeditors/dropdown-controller.spec.js
+++ b/src/Umbraco.Web.UI.Client/test/unit/app/propertyeditors/dropdown-controller.spec.js
@@ -22,8 +22,6 @@ describe('Drop down controller tests', function () {
expect(scope.model.config).toBeDefined();
expect(scope.model.config.items).toBeDefined();
expect(scope.model.config.multiple).toBeDefined();
- expect(scope.model.config.keyName).toBeDefined();
- expect(scope.model.config.valueName).toBeDefined();
});
it("should convert simple array to dictionary", function () {
@@ -39,14 +37,9 @@ describe('Drop down controller tests', function () {
$routeParams: routeParams
});
- expect(scope.model.config.items.length).toBe(3);
- for (var i = 0; i < scope.model.config.items.length; i++) {
- expect(scope.model.config.items[i].alias).toBeDefined();
- expect(scope.model.config.items[i].name).toBeDefined();
- //name and alias will be the same in this case
- expect(scope.model.config.items[i].alias).toBe("value" + i);
- expect(scope.model.config.items[i].name).toBe("value" + i);
- }
+ expect(scope.model.config.items["value0"]).toBe("value0");
+ expect(scope.model.config.items["value1"]).toBe("value1");
+ expect(scope.model.config.items["value2"]).toBe("value2");
});
@@ -54,11 +47,11 @@ describe('Drop down controller tests', function () {
scope.model = {
config: {
- items: [
- { alias: "value0", name: "Value 0" },
- { alias: "value1", name: "Value 1" },
- { alias: "value2", name: "Value 2" }
- ]
+ items: {
+ "value0" : "Value 0",
+ "value1" : "Value 1",
+ "value2" : "Value 2"
+ }
}
};
@@ -73,15 +66,11 @@ describe('Drop down controller tests', function () {
});
- it("should not allow an existing invalid dictionary", function () {
+ it("should not allow a non-array or non-dictionary", function () {
scope.model = {
config: {
- items: [
- { blah: "value0", name: "Value 0" },
- { blah: "value1", name: "Value 1" },
- { blah: "value2", name: "Value 2" }
- ]
+ items: true
}
};
diff --git a/src/Umbraco.Web.UI/App_Plugins/MarkdownEditor/markdowneditor.controller.js b/src/Umbraco.Web.UI/App_Plugins/MarkdownEditor/markdowneditor.controller.js
index 23d54869ca..7d8d2faf9f 100644
--- a/src/Umbraco.Web.UI/App_Plugins/MarkdownEditor/markdowneditor.controller.js
+++ b/src/Umbraco.Web.UI/App_Plugins/MarkdownEditor/markdowneditor.controller.js
@@ -1,7 +1,7 @@
angular.module("umbraco")
.controller("My.MarkdownEditorController",
//inject umbracos assetsServce and dialog service
-function ($scope, assetsService, dialogService, $log, umbImageHelper) {
+function ($scope, assetsService, dialogService, $log, imageHelper) {
//tell the assets service to load the markdown.editor libs from the markdown editors
//plugin folder
@@ -17,7 +17,7 @@ function ($scope, assetsService, dialogService, $log, umbImageHelper) {
"/app_plugins/markdowneditor/lib/markdown.editor.js"
])
.then(function () {
-
+
//this function will execute when all dependencies have loaded
var converter2 = new Markdown.Converter();
var editor2 = new Markdown.Editor(converter2, "-" + $scope.model.alias);
@@ -28,16 +28,18 @@ function ($scope, assetsService, dialogService, $log, umbImageHelper) {
dialogService.mediaPicker({ callback: function (data) {
- $(data.selection).each(function (i, item) {
- var imagePropVal = umbImageHelper.getImagePropertyVaue({ imageModel: item, scope: $scope });
- callback(imagePropVal);
- });
- }
+ $(data.selection).each(function (i, item) {
+ var imagePropVal = imageHelper.getImagePropertyVaue({ imageModel: item, scope: $scope });
+ callback(imagePropVal);
+ });
+ }
});
return true; // tell the editor that we'll take care of getting the image url
});
+ });
+
//load the seperat css for the editor to avoid it blocking our js loading TEMP HACK
assetsService.loadCss("/app_plugins/markdowneditor/lib/markdown.css");
});
\ No newline at end of file
diff --git a/src/Umbraco.Web/Editors/DataTypeController.cs b/src/Umbraco.Web/Editors/DataTypeController.cs
index 3246f8b86a..ba87ed07c3 100644
--- a/src/Umbraco.Web/Editors/DataTypeController.cs
+++ b/src/Umbraco.Web/Editors/DataTypeController.cs
@@ -118,11 +118,8 @@ namespace Umbraco.Web.Editors
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);
+ dtService.SaveDataTypeAndPreValues(dataType.PersistedDataType, formattedVal, (int)Security.CurrentUser.Id);
var display = Mapper.Map(dataType.PersistedDataType);
display.AddSuccessNotification(ui.Text("speechBubbles", "dataTypeSaved"), "");
diff --git a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs
index 324b9d6b4c..aaa3c86c10 100644
--- a/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/DatePropertyEditor.cs
@@ -33,21 +33,16 @@ namespace Umbraco.Web.PropertyEditors
protected override ValueEditor CreateValueEditor()
{
- var baseEditor = base.CreateValueEditor();
-
- return new DateValueEditor
- {
- View = baseEditor.View
- };
+ return new DateValueEditor(base.CreateValueEditor());
}
///
/// CUstom value editor so we can serialize with the correct date format (excluding time)
/// and includes the date validator
///
- private class DateValueEditor : ValueEditor
+ private class DateValueEditor : ValueEditorWrapper
{
- public DateValueEditor()
+ public DateValueEditor(ValueEditor wrapped) : base(wrapped)
{
Validators = new List { new DateTimeValidator() };
}
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePreValueEditor.cs
new file mode 100644
index 0000000000..11c03b1051
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePreValueEditor.cs
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using Umbraco.Core.Models;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Web.PropertyEditors
+{
+ ///
+ /// A pre-value editor for the 'drop down list multiple' property editor that ensures that 'multiple' is saved for the config in the db but is not
+ /// rendered as a pre-value field.
+ ///
+ ///
+ /// This is mostly to maintain backwards compatibility with old property editors. Devs can now simply use the Drop down property editor and check the multiple pre-value checkbox
+ ///
+ internal class DropDownMultiplePreValueEditor : DropDownPreValueEditor
+ {
+ public DropDownMultiplePreValueEditor()
+ {
+ var fields = CreatePreValueFields();
+ //add the multiple field, we'll make it hidden so it is not seen in the pre-value editor
+ fields.Add(new PreValueField
+ {
+ Key = "multiple",
+ Name = "multiple",
+ View = "hidden"
+ });
+ Fields = fields;
+ }
+
+ ///
+ /// Always
+ ///
+ ///
+ ///
+ ///
+ public override IDictionary FormatDataForEditor(IDictionary defaultPreVals, PreValueCollection persistedPreVals)
+ {
+ var returnVal = base.FormatDataForEditor(defaultPreVals, persistedPreVals);
+ //always add the multiple param to true
+ returnVal["multiple"] = "1";
+ return returnVal;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs
new file mode 100644
index 0000000000..ffe1882682
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/DropDownMultiplePropertyEditor.cs
@@ -0,0 +1,39 @@
+using Umbraco.Core;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Web.PropertyEditors
+{
+ ///
+ /// A property editor to allow multiple selection of pre-defined items
+ ///
+ ///
+ /// 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.DropDownListMultiple, "Dropdown list multiple", "dropdown")]
+ public class DropDownMultiplePropertyEditor : DropDownPropertyEditor
+ {
+ protected override ValueEditor CreateValueEditor()
+ {
+ return new DropDownMultipleValueEditor(base.CreateValueEditor());
+ }
+
+ protected override PreValueEditor CreatePreValueEditor()
+ {
+ return new DropDownMultiplePreValueEditor();
+ }
+
+ }
+
+ internal class DropDownMultipleValueEditor : ValueEditorWrapper
+ {
+ public DropDownMultipleValueEditor(ValueEditor wrapped) : base(wrapped)
+ {
+ }
+
+ public override object FormatDataForPersistence(Core.Models.Editors.ContentPropertyData editorValue, object currentValue)
+ {
+ return base.FormatDataForPersistence(editorValue, currentValue);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs
index 1db5cc9c3d..b9d6f3fd67 100644
--- a/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/DropDownPreValueEditor.cs
@@ -7,12 +7,42 @@ using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
+using umbraco;
namespace Umbraco.Web.PropertyEditors
{
internal class DropDownPreValueEditor : PreValueEditor
{
+ public DropDownPreValueEditor()
+ {
+ Fields = CreatePreValueFields();
+ }
+
+ ///
+ /// Creates the pre-value fields
+ ///
+ ///
+ protected List CreatePreValueFields()
+ {
+ return new List
+ {
+ new PreValueField
+ {
+ Description = "Add and remove values for the drop down list",
+ //we're going to call this 'items' 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)
+
+ //It's also important to note that by default the dropdown angular controller is expecting the
+ // config options to come in with a property called 'items'
+ Key = "items",
+ Name = ui.Text("editdatatype", "addPrevalue"),
+ View = "Views/PropertyEditors/dropdown/dropdown.prevalue.html"
+ }
+ };
+ }
+
///
/// The editor is expecting a json array for a field with a key named "items" so we need to format the persisted values
/// to this format to be used in the editor.
@@ -25,7 +55,8 @@ namespace Umbraco.Web.PropertyEditors
var dictionary = PreValueCollection.AsDictionary(persistedPreVals);
var arrayOfVals = dictionary.Select(item => item.Value).ToList();
- return new Dictionary { { "items", arrayOfVals } };
+ //the items list will be a dictionary of it's id -> value we need to use the id for persistence for backwards compatibility
+ return new Dictionary { { "items", arrayOfVals.ToDictionary(x => x.Id, x => x.Value) } };
}
///
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs
index 6f8a8429a6..956233dd98 100644
--- a/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/DropDownPropertyEditor.cs
@@ -1,36 +1,56 @@
-using System.Collections.Generic;
+using System;
+using System.Linq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
using Umbraco.Core;
+using Umbraco.Core.Logging;
using Umbraco.Core.PropertyEditors;
using umbraco;
namespace Umbraco.Web.PropertyEditors
{
- [PropertyEditor(Constants.PropertyEditors.DropDownList, "Dropdown list", "dropdown")]
- public class DropDownPropertyEditor : PropertyEditor
+ ///
+ /// A property editor to allow the individual selection of pre-defined items.
+ ///
+ ///
+ /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked
+ /// 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.DropDownList, "Dropdown list", "dropdown", ValueType = "INT")]
+ public class DropDownPropertyEditor : DropDownWithKeysPropertyEditor
{
+
+ ///
+ /// 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 ValueEditor CreateValueEditor()
+ {
+ return new DropDownValueEditor(base.CreateValueEditor());
+ }
+
+ }
+
+ ///
+ /// A property editor to allow the individual selection of pre-defined items.
+ ///
+ ///
+ /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked
+ /// 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.DropdownlistPublishingKeys, "Dropdown list, publishing keys", "dropdown", ValueType = "INT")]
+ public class DropDownWithKeysPropertyEditor : PropertyEditor
+ {
+
+ ///
+ /// Return a custom pre-value editor
+ ///
+ ///
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 'items' 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)
-
- //It's also important to note that by default the dropdown angular controller is expecting the
- // config options to come in with a property called 'items'
- Key = "items",
- Name = ui.Text("editdatatype", "addPrevalue"),
- View = "Views/PropertyEditors/dropdown/dropdown.prevalue.html"
- }
- }
- };
-
- return editor;
+ return new DropDownPreValueEditor();
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownValueEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownValueEditor.cs
new file mode 100644
index 0000000000..4d6a951c47
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/DropDownValueEditor.cs
@@ -0,0 +1,59 @@
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Models;
+using Umbraco.Core.Models.Editors;
+using Umbraco.Core.PropertyEditors;
+using Umbraco.Core.Services;
+using System.Linq;
+
+namespace Umbraco.Web.PropertyEditors
+{
+ ///
+ /// A custom value editor for the drop down so that we can ensure that the 'value' not the ID get's put into cache
+ ///
+ ///
+ /// This is required for legacy/backwards compatibility, otherwise we'd just store the string version and cache the string version without
+ /// needing additional lookups.
+ ///
+ internal class DropDownValueEditor : ValueEditorWrapper
+ {
+ private readonly DataTypeService _dataTypeService;
+
+ internal DropDownValueEditor(IDataTypeService dataTypeService, ValueEditor wrapped)
+ : base(wrapped)
+ {
+ _dataTypeService = (DataTypeService)dataTypeService;
+ }
+
+ public DropDownValueEditor(ValueEditor wrapped)
+ : this(ApplicationContext.Current.Services.DataTypeService, wrapped)
+ {
+ }
+
+ ///
+ /// Need to lookup the pre-values and put the string version in cache, not the ID (which is what is stored in the db)
+ ///
+ ///
+ ///
+ public override object FormatValueForCache(Property property)
+ {
+ var preValId = property.Value.TryConvertTo();
+ if (preValId.Success)
+ {
+ var preVals = _dataTypeService.GetPreValuesCollectionByDataTypeId(property.PropertyType.DataTypeDefinitionId);
+ if (preVals != null)
+ {
+ var dictionary = PreValueCollection.AsDictionary(preVals);
+ if (dictionary.Any(x => x.Value.Id == preValId.Result))
+ {
+ return dictionary.Single(x => x.Value.Id == preValId.Result).Value.Value;
+ }
+
+ LogHelper.Warn("Could not find a pre value with ID " + preValId + " for property alias " + property.Alias);
+ }
+ }
+
+ return base.FormatValueForCache(property);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs
new file mode 100644
index 0000000000..d320190b67
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/DropDownWithKeysPropertyEditor.cs
@@ -0,0 +1,27 @@
+using Umbraco.Core;
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Web.PropertyEditors
+{
+ ///
+ /// A property editor to allow the individual selection of pre-defined items.
+ ///
+ ///
+ /// Due to remaining backwards compatible, this stores the id of the drop down item in the database which is why it is marked
+ /// 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.DropdownlistPublishingKeys, "Dropdown list, publishing keys", "dropdown", ValueType = "INT")]
+ public class DropDownWithKeysPropertyEditor : PropertyEditor
+ {
+
+ ///
+ /// Return a custom pre-value editor
+ ///
+ ///
+ protected override PreValueEditor CreatePreValueEditor()
+ {
+ return new DropDownPreValueEditor();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs
index 53c5ee94ad..7d15eedd34 100644
--- a/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/LabelPropertyEditor.cs
@@ -11,12 +11,7 @@ namespace Umbraco.Web.PropertyEditors
protected override ValueEditor CreateValueEditor()
{
- var baseEditor = base.CreateValueEditor();
-
- return new LabelValueEditor
- {
- View = baseEditor.View
- };
+ return new LabelValueEditor(base.CreateValueEditor());
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/LabelValueEditor.cs b/src/Umbraco.Web/PropertyEditors/LabelValueEditor.cs
index 2e514c4463..04d41ff6b1 100644
--- a/src/Umbraco.Web/PropertyEditors/LabelValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/LabelValueEditor.cs
@@ -5,8 +5,12 @@ namespace Umbraco.Web.PropertyEditors
///
/// Custom value editor to mark it as readonly
///
- internal class LabelValueEditor : ValueEditor
+ internal class LabelValueEditor : ValueEditorWrapper
{
+ public LabelValueEditor(ValueEditor wrapped) : base(wrapped)
+ {
+ }
+
///
/// This editor is for display purposes only, any values bound to it will not be saved back to the database
///
diff --git a/src/Umbraco.Web/PropertyEditors/ValueEditorWrapper.cs b/src/Umbraco.Web/PropertyEditors/ValueEditorWrapper.cs
new file mode 100644
index 0000000000..06419aa336
--- /dev/null
+++ b/src/Umbraco.Web/PropertyEditors/ValueEditorWrapper.cs
@@ -0,0 +1,18 @@
+using Umbraco.Core.PropertyEditors;
+
+namespace Umbraco.Web.PropertyEditors
+{
+ ///
+ /// Useful when returning a custom value editor when your property editor is attributed, it ensures the attribute
+ /// values are copied across to your custom value editor.
+ ///
+ public class ValueEditorWrapper : ValueEditor
+ {
+ public ValueEditorWrapper(ValueEditor wrapped)
+ {
+ this.View = wrapped.View;
+ this.ValueType = wrapped.ValueType;
+ this.Validators = wrapped.Validators;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 268b6396ee..966d3a52b1 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -318,10 +318,14 @@
+
+
+
+