diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs
index 11f915fabd..b3db026c89 100644
--- a/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs
+++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/GridValueConverter.cs
@@ -12,6 +12,9 @@ using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Core.PropertyEditors.ValueConverters
{
+ ///
+ /// This ensures that the grid config is merged in with the front-end value
+ ///
[DefaultPropertyValueConverter(typeof(JsonValueConverter))] //this shadows the JsonValueConverter
[PropertyValueType(typeof(JToken))]
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
@@ -90,7 +93,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
}
catch (Exception ex)
{
- LogHelper.Error("Could not parse the string " + sourceString + " to a json object", ex);
+ LogHelper.Error("Could not parse the string " + sourceString + " to a json object", ex);
}
}
diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs
new file mode 100644
index 0000000000..8ad0b7d69d
--- /dev/null
+++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs
@@ -0,0 +1,67 @@
+using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Umbraco.Core.Logging;
+using Umbraco.Core.Models.PublishedContent;
+
+namespace Umbraco.Core.PropertyEditors.ValueConverters
+{
+ ///
+ /// This ensures that the cropper config (pre-values/crops) are merged in with the front-end value.
+ ///
+ [DefaultPropertyValueConverter(typeof (JsonValueConverter))] //this shadows the JsonValueConverter
+ [PropertyValueType(typeof (JToken))]
+ [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
+ public class ImageCropperValueConverter : JsonValueConverter
+ {
+ public override bool IsConverter(PublishedPropertyType propertyType)
+ {
+ return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.ImageCropperAlias);
+ }
+
+ public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview)
+ {
+ if (source == null) return null;
+ var sourceString = source.ToString();
+
+ if (sourceString.DetectIsJson())
+ {
+ JObject obj;
+ try
+ {
+ obj = JsonConvert.DeserializeObject(sourceString);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error("Could not parse the string " + sourceString + " to a json object", ex);
+ return sourceString;
+ }
+
+ //need to lookup the pre-values for this data type
+ //TODO: Change all singleton access to use ctor injection in v8!!!
+ var dt = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(propertyType.DataTypeId);
+
+ if (dt != null && dt.IsDictionaryBased && dt.PreValuesAsDictionary.ContainsKey("crops"))
+ {
+ var cropsString = dt.PreValuesAsDictionary["crops"].Value;
+ JArray crops;
+ try
+ {
+ crops = JsonConvert.DeserializeObject(cropsString);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error("Could not parse the string " + cropsString + " to a json object", ex);
+ return sourceString;
+ }
+ obj["crops"] = crops;
+ }
+
+ return obj;
+ }
+
+ //it's not json, just return the string
+ return sourceString;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 3476d1fcc3..cee2f8ee3f 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -488,6 +488,7 @@
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
index 8272f032ee..29176da102 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js
@@ -580,11 +580,11 @@ angular.module("umbraco")
// *********************************************
- // INITIALISATION
+ // Initialization
// these methods are called from ng-init on the template
// so we can controll their first load data
//
- // intialisation sets non-saved data like percentage sizing, allowed editors and
+ // intialization sets non-saved data like percentage sizing, allowed editors and
// other data that should all be pre-fixed with $ to strip it out on save
// *********************************************
diff --git a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs
index a76b39f187..e592c157aa 100644
--- a/src/Umbraco.Web/ImageCropperTemplateExtensions.cs
+++ b/src/Umbraco.Web/ImageCropperTemplateExtensions.cs
@@ -119,6 +119,10 @@
if (mediaItem.HasProperty(propertyAlias) && mediaItem.HasValue(propertyAlias))
{
+ //TODO: We should change this, the default value is JObject now, this means we are ToString() ing the value,
+ // then re-deserializing it back to json and then to a strongly typed model.
+ // With a tiny bit of work we can make this more efficient since it's already a JObject.
+
imageCropperValue = mediaItem.GetPropertyValue(propertyAlias);
// get the raw value (this will be json)