Back
1

Improving the AEM Core Image Component Authoring Experience

August 22, 2022

Core Components are recommended as a best practice in AEM. They are intended to speed up development time and reduce maintenance costs. In this post I demonstrate how it's possible to customize and extend the Java Script client library associated with the Core Image component in order to improve the authoring experience when using Dynamic Media. 

Dynamic Media Use Case

Assume that our WKND tutorial project has recently been configured to enable Dynamic Media. Images contain the necessary Dynamic Media metadata properties and we've configured multiple Image Presets for use in the authoring instance.

A content author submits an enhancement request ticket to improve the authoring experience:

  1. Maintain the selected Image Preset within the Metadata dialog tab when toggling between the Image Preset and Smart Crop options
  2. Limit the list of Image Preset options to only those that begin with the prefix 'wknd-'
  3. Select the 'wknd-preset-1' option by default

The OOTB authoring experience is reflected in the video below:  

Solution Development

To begin, we should review the client library provided by the Core Image component. Specifically, we want to look at the JavaScript library that is loaded in the editor when content authors are making changes:

- core/wcm/components/image/v2/image/clientlibs/editor/js/image.js  [View on Github]

In order to achieve the three objectives described above we start by defining a client library for the Image Proxy component associated with the WKND site. 

Core Image Editor Client Library

Next, we write the logic required to achieve the three objectives defined as our acceptance criteria. 

/**
 * 
 * Set Default and Limit Preset Items
 * @desc:Responsible for setting responsive as the default preset select option and removing items that do not contain wknd- prefix
 *
 */
 (function($) {
  "use strict";

  var dialogContentSelector = ".cmp-image__editor";
  var $dialogContent;
  var $dynamicMediaGroup;
  var presetTypeSelector = ".cmp-image__editor-dynamicmedia-presettype";
  var smartCropRenditionDropDownSelector = ".cmp-image__editor-dynamicmedia-smartcroprendition";
  var imagePresetDropDownSelector = ".cmp-image__editor-dynamicmedia-imagepreset";


  $(document).on("dialog-loaded", function(e) {

      var $dialog = e.dialog;
      $dialogContent = $dialog.find(dialogContentSelector);
      $dynamicMediaGroup = $dialogContent.find(".cmp-image__editor-dynamicmedia");

      var $imagePresetDropDownSelector = $(imagePresetDropDownSelector);
      var $imagePresetDropDownSelectorItems = $imagePresetDropDownSelector.find('coral-select-item');
      var currentDefaultEl = $imagePresetDropDownSelector.find('[selected]');
      var currentDefaultText = '';
      var isDefaultInValid = false;

      // if presetTypeSelector does not exist return early
      if ($(presetTypeSelector).length < 1) {
          return;
      }

       if (currentDefaultEl.length > 0 && currentDefaultEl[0].innerText) {
          currentDefaultText = currentDefaultEl[0].innerText.toLowerCase();
      }

      if (currentDefaultText.indexOf('wknd-') < 0) {
          isDefaultInValid = true;
      }

      for (var i = 0; i < $imagePresetDropDownSelectorItems.length; i++) {

          //remove non wknd- prefixed and responsive items
          if ($imagePresetDropDownSelectorItems[i].innerText.toLowerCase().indexOf('wknd-') < 0) {
              $imagePresetDropDownSelectorItems[i].remove();
          }

          //set wknd-preset-1 as default
          if (isDefaultInValid && $imagePresetDropDownSelectorItems[i].innerText.toLowerCase() == 'wknd-preset-1') {
              $imagePresetDropDownSelectorItems[i].selected = true;

          }

      }

  });


  $(document).on("change", dialogContentSelector + " " + presetTypeSelector, function(e) {

      switch (e.target.value) {
          case "smartCrop":
              //stop propagation of event in order to prevent core image client lib from detecting this event. 
              //necessary to prevent resetting of imagePresetDropDownSelector
              e.stopPropagation();
              e.stopImmediatePropagation();
              $dynamicMediaGroup.find(imagePresetDropDownSelector).parent().hide();
              $dynamicMediaGroup.find(smartCropRenditionDropDownSelector).parent().show();
              break;
          default:
              break;
      }
  });

})(jQuery);

 

It's important to understand that the client library created for our proxy component will load first, and then the client library included with the Core Image component will load. 

By leveraging the same selectors and event listeners as the OOTB JavaScript, we can make sure these two files play nicely together. By leveraging the stopPropogation and stopImmediatePropogation functions, it's possible to control which events reach the OOTB JavaScript and which do not.

The video below captures the result of our efforts. The selected Image Preset is maintained when authors toggle between options, the Image Preset list is limited to only those items that begin with the 'wknd-' prefix, and the preferred default option is selected for an improved authoring experience.