Frustratingly when editing an component in Sitecore 8 using either edit frame (or a Custom Experience Editor Button) the component datasource does not refresh, you need to click the save button afterwards to refresh the page and see your changes.
Content Editors could find this confusing, especially if they have just added some items to a multi-list (e.g a list of products) in the modal window
and the new/updated products do not show on the product listing component.
Someone on the Sitecore Slack Channel also needed to solve this issue this week which prompted me to write this up.
Google didn’t turn up any solutions so I set out to try and figure out how to make the page refresh and show the changes. After trying a couple of different approaches I settled on overriding two standard Pipelines under :
Sitecore.Shell.Applications.ContentManager.ReturnFieldEditorValues.SetValues
and
Sitecore.Shell.Applications.ContentManager.ReturnFieldEditorValues.ReturnAndClose
To get the code for these I first decompiled the Sitecore.Client dll and copied the SetValues.cs
and ReturnAndClose.cs classes. My customised versions are below, you will need to reference a number of Sitecore classes such as: Sitecore , Sitecore.Data, Sitecore.Shell.
SetValuesAndSave.cs:
public class SetValuesAndSave
{
public void Process( ReturnFieldEditorValuesArgs args)
{
args.Options.SaveItem = true;
foreach ( FieldInfo fieldInfo in args.FieldInfo.Values)
{
Control subControl = Context.ClientPage.FindSubControl(fieldInfo.ID);
if (subControl != null)
{
string str1;
if (subControl is IContentField)
str1 = StringUtil.GetString((subControl as IContentField ).GetValue());
else
str1 = StringUtil.GetString(ReflectionUtil .GetProperty(subControl, “Value”));
if (str1 != “__#!$No value$!#__”)
{
string str2 = fieldInfo.Type.ToLowerInvariant();
if (str2 == “rich text” || str2 == “html”)
str1 = str1.TrimEnd(‘ ‘);
foreach ( FieldDescriptor fieldDescriptor in args.Options.Fields)
{
if (fieldDescriptor.FieldID == fieldInfo.FieldID)
{
ItemUri itemUri = new ItemUri(fieldInfo.ItemID, fieldInfo.Language, fieldInfo.Version, Factory.GetDatabase(fieldDescriptor.ItemUri.DatabaseName));
if (fieldDescriptor.ItemUri == itemUri)
fieldDescriptor.Value = str1;
Item item = Factory.GetDatabase(fieldDescriptor.ItemUri.DatabaseName).GetItem(itemUri.ItemID);// Save item as above doesn’t persist after postback
if (item != null)
{
item.Editing.BeginEdit();
item.Fields[fieldInfo.FieldID.ToString()].Value = str1;
item.Editing.EndEdit();
}
}
}
}
}
}
}
ReturnCloseAndRefresh.cs:
public class ReturnCloseAndRefresh
{
public void Process( ReturnFieldEditorValuesArgs args)
{
SheerResponse.SetDialogValue(args.Options.ToUrlHandle().ToHandleString());
SheerResponse.SetModified(true );
SheerResponse.CloseWindow();//Reload the page editor after closing
SheerResponse.Eval(“window.top.location.reload();” );
}
}
Now you have two custom pipelines you will need to register them with a patch file like so:
<processors>
<uiReturnFieldEditorValues>
<processor type=”ScExtensions.Pipelines.SetValuesAndSave, ScExtensions”
patch:instead=”processor[@type=’Sitecore.Shell.Applications.ContentManager.ReturnFieldEditorValues.SetValues’]”/>
<processor type=”ScExtensions.Pipelines.ReturnCloseAndRefresh, ScExtensions”
patch:instead=”processor[@type=’Sitecore.Shell.Applications.ContentManager.ReturnFieldEditorValues.ReturnAndClose’]”/>
</uiReturnFieldEditorValues></processors>
Thats it, once you’ve build and deployed your code you should find that any changes made in the field editor modal window are automatically saved for you and the page is auto-refreshed showing the updates.
One potential issue here is that by firing the refresh the content editor may loose other changes they have made to the page and not yet saved but the do get prompted about the refresh so will be aware of this.
I’d love to know of a better/easier way of doing this so feel free to let me know if you know of one.