One Fewer Edit Frame

Recently I had a client that wanted an ‘enhanced’ Experience Editor. This was summarized as fewer clicks for the editors to perform their authoring. What made this request a little more challenging than normal was some of the fields which required editing where of type checkbox, date, and multi-select.

The following findings were based on Sitecore Experience Platform 8.2 update 4 and have not been tested on Sitecore XP 9, but my suspicion is that it will continue to work.

The Challenge

As most Sitecore developers know these types of complex fields cannot traditionally be displayed directly in the Experience Editor, and we usually end up leveraging some form of an Edit Frame, either custom built or via the very handy BeginEditFrame command via Glass.Mapper.

BeginEditFrame is very helpful in providing otherwise non-access to complex field types but does create the problem of several additional clicks, in my example it creates 3 clicks.

Enhanced Editing with Edit Frame

To make the above happen the code required is straight forward

@using (BeginEditFrame(Model, "Edit Frame", z => z.StickyDate,
                    z=> z.HideContactName,
                    z=> z.NewsandAnnouncementCategory))
    Click To Launch the Edit Frame


After a little spelunking into how the Experience Editor, I discovered that fields upon edit trigger a JavaScript function Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);.

The parameters for this are pulled from the hidden span fields with a class of ‘scChromeDate’ each field gets assigned. It looks something like the following

Enhanced Editing inline

To make this work we need to render the following values onto the page to support the setFieldValue method.

  • current page’s ID scrubbed of all brackets and dashes, I find the following works well Sitecore.Data.ID.Encode(PageId)
  • current language of the page being edited
  • current version of the page
  • the field’s ID scrubbed of all brackets and dashes

To get access to these values, I include them in as data-* attributes on the HTML, thus my checkbox would have the following HTML. (Note: my model uses GlassMapper)

< input id="hidcontact" class="editcheckbox" checked="checked"
   data-itemid="@Sitecore.Data.ID.Encode(Model.Id)" / >
< label for="hidcontact">Hide Contact Name< / label>

With the data available next we need to trigger the change or action associated with the item, in this sample for checkbox we want to handle the click event. So, the JavaScript would be something like this

 jQuery('.editcheckbox', namespace).click(function () {            
        var itemId = jQuery(this).attr('data-itemid');
        var itemLanguage = jQuery(this).attr('data-language');
        var itemVersion = jQuery(this).attr('data-version');
        var fieldId = jQuery(this).attr('data-fieldid');

        if (jQuery(this).prop('checked')) {
            SetNewFieldValue('1', itemId, 
        else {
            SetNewFieldValue('0', itemId,

In the above snippet, you will see that I make a call to SetNewFieldValue. This is a global function I wrote that facilitates the actual call to the Sitecore method. Having it as separate method allows the logic to be used across my site.

 function SetNewFieldValue(newFieldValue, itemId, itemLanguage, itemVersion, fieldId) {
  //Create the JS Item Uri Object...the last parameter is a revision, which we don't have easy access to so blank is passed in.
  var scItemUri = new Sitecore.ItemUri(itemId, itemLanguage, itemVersion, '');
  Sitecore.WebEdit.setFieldValue(scItemUri, fieldId, newFieldValue);

You may have noticed that setFieldValue has a parameter called scItemUri but we are not generating this value at render via something like Sitecore.Context.Item.Uri. That is because setFieldValue is expecting a JavaScript object, which we can create via the call to Sitecore.ItemUri.

This little bit of JavaScript then allows are edit experience to become

Enhanced Editing inline

Bonus – Information For the multi-select

At base of any multi-select type field is a simple pipe-delimited string of item GUIDs. This simplicity of data storage means we can leverage our SetNewFieldValue method, by simplify passing in a newly generated pipe-delimited string of selected items.

The following is useful for very small multi-select list, such as for taxonomy usage, but has the possibility of significantly effecting the performance of the Experience Editor, so be smart about how you apply the following.

To make this happen, within in the associated controller for the rendering we load up all the items normally associated to the pick list in some sort of Name-Value pair, collecting the name and ID of each item. As part of this you’ll also need to indicate what values are currently selected…my code looks like this and leverages a custom object for the name-value pair.

//C# Controller code
//Setup Category Lists
viewmodel.CategoriesListEditing = new List();
var allCategories = Sitecore.Context.Database
.SelectItems(Sitecore.Context.Site.RootPath + "/Content Taxonomy[@@templateid='{30D58A48-789D-49D2-BBEE-360E5DB10A68}']/*").ToList();
if (allCategories.Any())
   var hasCategories = viewmodel.NewsandAnnouncementCategory != null && viewmodel.NewsandAnnouncementCategory.Any();
   foreach (var cat in allCategories)
      viewmodel.CategoriesListEditing.Add(new NameValuePairObject(
       !hasCategories?false: viewmodel.NewsandAnnouncementCategory.Any(cv => cv == cat.ID.ToGuid())));

This is rendered out into a checkbox list, whenever a box is clicked this trigger the following method.

jQuery('.newscatcheckbox', namespace).click(function () {
    var itemId = jQuery(this).attr('data-itemid');
    var itemLanguage = jQuery(this).attr('data-language');
    var itemVersion = jQuery(this).attr('data-version');
    var fieldId = jQuery(this).attr('data-fieldid');

    var idList = "";
    //Get all checkboxes and determine if the item is selected
    jQuery('.newscatcheckbox', namespace).each(function (index) {
        if (jQuery(this).prop('checked')) {
            if (idList !== '') idList += '|';
            idList += jQuery(this).attr("id");
    SetNewFieldValue(idList, itemId, itemLanguage, itemVersion, fieldId);


That’s all it took to enhancing the Experience Editor one step further for your authors. Let me know if you try this out or have other suggestions that could be leveraged in enhancing the Experience Editor.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s