Classic to Touch UI Migration for AEM: More Tips from Experience

Liubou Masiuk
Exadel Marketing Technology Practice
7 min readOct 17, 2019

In our previous post on Classic to TouchUI migration we described our overall “Hybrid Mode” approach to migrating an entirely Classic UI component library to Touch UI using AEM’s compatibility mode. In the post, we alluded to some “quirks” that we encountered. In this new post, we go into much more detail about these quirks and how to deal with some of these quirks.

Although the Hybrid Mode is extremely useful it has some limitations that can prevent the development team from adopting TouchUI without additional effort on large projects. Here are some of those issues we encountered and the solutions our development team came up with.

Author can’t drag & drop images while editing a component

The ClassicUI Widgets library provides a SmartImage component for uploading and processing images. Image assets by default can be uploaded in two different ways:

  • From the file system
  • From the DAM (Digital Asset Manager) by dragging the image from the page content finder panel on the left side
DAM Assets panel (TouchUI interface)
DAM Assets panel (TouchUI interface)

Let’s dive deep into the technical details of TouchUI implementation. The compatibility mode renders a ClassicUI dialog inside an iframe. For some reason the compatible mode doesn’t have any logic for tracking drag & drop events out-of-the-box. This restricts authors from dragging images out of the Assets panel (as they are used to doing it within the ClassicUI experience). This means they do not have a way to place the image into the component. Moreover, when an image field is required, the author doesn’t have the option to complete component configuration because of an empty required field.

Solution

To solve this problem we decided to extend the Standard SmartImage component to render a pathfield in addition to existing functionality. As a result, the author gets the ability to select an image by using pathfield and the image appears inside the SmartImage area to preview and/or change the image if needed. For non-existing paths (or non-image paths) the field is highlighted as invalid.

Required Image area inside the component
Required Image area inside the component
  1. Re-register the original htmlsamartimage xtype with an inherent custom one that extends the original CQ HtmlSmartImage widget. On the initialization of the new widget, we add an additional PathField widget to the component containers. Additionally, we provide little updates to the default widget layout that’s a common UI update for ExtJS-based UIs.
  2. Binding controls (PathFields) in all HTMLSmartImages. First of all, we prepare helpers by creating methods for getting and setting values from PathPicker and the same methods for the original component. The first pair is setValue and getValue of the PathField, which is the easy part. The tricky part is dealing with the original component value. HTMLSmartImage doesn’t store its value in an accessible state.

To get the current image path is easily done through using the this.fileReferenceField.getValue() method. But to set the value to the original widget we need to emulate an image resource drop on the component. We can manage that in the following way:

Now when we have all value accessors we need to know when the original and when the Pathfield value are changing. To track Pathfield changes we can use a ‘blur’ event. For the original widget the ‘imagestate’ event is the most suitable. We need to track two types of image state changes: ‘originalremoved’ and ‘originalavailable’, so the listener can be the following:

Now, it’s ready for binding. To keep the validation mechanism in the new implementation, we override the original validation logic for the embedded pathfield instance.

All scaffolding fields dialogs are disabled

AEM Scaffolding mode allows an author to easily create pages based on a specific scaffold form structure. Scaffolds are extremely useful for creating well-defined structured content (e.g., articles, blog posts).

In Hybrid Mode all scaffolding form fields are disabled, which means they can’t be edited.

Scaffolding form example
Scaffolding form example

Solution

Including the cq.security library into the page’s JSP solved the issue and the scaffolding forms started working properly.

Hybrid dialog closes without saving data when clicking outside of the dialog area

All components are edited inside the component configuration dialog window, which pops up in edit mode.

Editing a component in AEM (TouchUI interface)
Editing a component in AEM (TouchUI interface)

There is a small difference in user experience in Hybrid and TouchUI dialogs:

  • If a user clicks away from the TouchUI dialog, nothing happens.
  • If a user clicks away from the hybrid dialog, it closes without saving entered data.

This means that all unsaved data is going to be lost in the event of an accidental click outside the component! Needless to say this is quite annoying for authors.

Solution

Luckily the solution is pretty simple. Initially, the dialog backdrop is in “modal” mode. In order to change the dialog backdrop mode the dialog’s JSP file needs to be overlaid and the dialog backdrop mode set to the “static” value.

Some dialog fields do not fit the dialog window area

As we already described before, UI dialogs render in an iframe inside the TouchUI dialog window. This dialog window sometimes does not fit all dynamic content, sometimes causing a weird layout where extra scrollbars appear inside the dialog.

Additional scroll element for the component in Hybrid Mode
Additional scroll element for the component in Hybrid Mode

Solution

To overcome this inconvenience, we overlay the JSP file that contains all configuration settings for properly rendering dialogs in the compatibility mode. This JSP file is placed within the following under the following path:

apps/cq/gui/components/authoring/compat/components/dialog/dialog.jsp

We change the window width and height to consider the original dialog’s dimensions, as well as the browser’s window size.

We handle this situation via script that actually provides bind between the Touch UI (Coral) wrapper and embedded Classic dialog in iframe. The event “dialogwrapper-ready” + ns is needed for that with pre-calculated width and height as handler function parameters. It’s also possible to do your own recalculation and then set the width and height to the Coral Dialog content:

Some components can’t be edited in TouchUI (easily)

The authoring experience is one of the most important points to consider while implementing components in AEM. Imagine a carousel component that contains a number of slides. In Edit mode, it’s better to render all carousel slides as a column so that the author can easily rearrange the slide order and access all of them simultaneously without switching between slides. There is one important difference between ClassicUI and TouchUI:

  • In ClassicUI the authoring elements (e.g., editbars) are a part of the markup that is rendered with the component in Edit mode.
  • In TouchUI the authoring elements are rendered in an overlay. Final component markup is rendered in an iframe. The combination of these conditions leads an author to the situation when it’s not possible to interact with the component in Edit mode at all (e.g., click buttons, flip through the slides of a carousel).

So we face cases where a couple of components in our library require some interaction before the user can start the editing process, but this can not be easily achieved in TouchUI.

Solutions

However, there are a couple of fixes that might be considered as possible solutions:

  1. There is a quick and simple workaround that requires no dev effort: all editable components can be found in the Content Tree and there is a wrench icon next to each one of them that opens the editing dialog.
Page Content Tree in TouchUI interface
Page Content Tree in TouchUI interface

2. For complex components with lots of subcomponents the markup of the component in Edit mode can be changed to make all ‘hidden’ component areas open to Author’s ‘eyes’. This would mean everything is visible and accessible through Edit mode.

3. As a best practice, Adobe provides a solution to support such an authoring experience case inside AEM Core Components. Carousel Component and Tabs Component use the Select Panel option in the component toolbar to reorder the slides and views and change the currently previewed element.

Out-of-the-box solution for reaching content hidden from authoring
Out-of-the-box solution for reaching content hidden from authoring

The “unlock page” button does not work

There is a standard AEM option to lock and unlock the page for changes. While validating the TouchUI migration approach, we found a situation where the author couldn’t revert a ‘locked’ page to its initial state. Fortunately this functionality works properly via the AEM Site Console.

‘Lock’ option in TouchUI interface
‘Lock’ option in TouchUI interface

A similar problem is described here and here.

Solution

The error message in the browser console says that it “Cannot read property ‘shared’ of undefined”. The root cause lies in a missing client library ‘cq.shared’.

Error message while dealing with ‘Locking/Unlocking’ functionality
Error message while dealing with ‘Locking/Unlocking’ functionality

Including of ‘cq.shared’ library into the page’s JSP solves the problem and the “Unlock page” button starts working as expected.

Authors: Volha Lunkova, Liubou Masiuk, Aliaksei Stsefanovich

Originally published at https://exadel.com on October 17, 2019.

--

--