Article summary

Summary
Discusses the following points:
  • how to develop an AEM 6 Touch UI component. 
  • how to use a custom xtype to work in an AEM 6 Touch UI.
  • how to use the component in both the Touch UI and classic views. 
A special thank you to Justin Edelson, a high contributor in the AEM community for his help during this development article.  
Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (beginner - intermediate)
Required Skills
JCR nodes, JavaScript, HTML
Tested On Adobe Experience Manager 6

Introduction

You can configure Adobe Experience Manager (AEM) 6 so that a custom xtype (that may be developed in an earlier version of AEM) works in the AEM 6 Touch UI. A custom xtype is an ExtJS script that uses the AEM widget API. By default, an AEM component that uses a custom xtype works in AEM classic view. However, a component that uses a custom xtype may not work in AEM 6 Touch UI. You configure AEM 6 to make a custom xtype work in AEM 6 Touch UI, as shown in this illustration.

TouchXType

Note:

In the Touch UI view, components are located on the side rail. In the AEM classic view, components are located in the AEM side kick. 

The AEM component uses a custom xtype that is part of a multifield dialog. When the user clicks the Add Item button, the widget that is based on the custom xtype appears, as shown in the previous illustration. Notice that there is a Term input field and a Definition Text area (these are defined in a JS script that defines the custom xtype and is shown later in this article). When the user enters values into these fields, the values are displayed on the AEM web page. 

This article creates a custom AEM 6 component that uses a custom xtype developed using the AEM widget API. The name of the component is named defination-list2 and appears on the AEM side rail, as shown in the following illustration. 

siderail

Note:

For information about the AEM widget API, see Widgets API Documentation.

The following illustration shows the project files created in this development article.

ProjectFiles
Section Description
A The acs-commons project that contains the client lib folder that contains the xtype script. You download and build this project in this article.     
B The client libs folder that defines the custom xtype. The category for this client libs folder is cq.widgets. It is strongly recommended that you place custom xtypes in a client libs folder with the cq.widgets category.  
C The js script that defines the custom xtype. The name of the custom xtype is multifieldpanel.
D The custom definition-list2 component.
E The custom definition-list2 component dialog - which is made up of JCR nodes. 

This development article steps you through how to build an AEM 6 component that uses a custom xtype named multifieldpanel

Download and build the acs-commons project 

The first step is to download and build the acs-commons project that is located from the following GitHub repository:

https://github.com/Adobe-Consulting-Services/acs-aem-commons/

Fork the repository to make a copy of it. Download the forked version by using GitHub clone command:

git clone git://<URL TO THE FORKED REPOSITOY>

This command downloads the forked repository to your local Github folder. Now you can use Maven to build and deploy the acs-commons project to Adobe Experience Manager 6. 

Note:

For more information about setting up Maven, see: Maven in 5 Minutes.

Navigate to your local folder to where the acs-commons files are located. Build and deploy the project by using the following Maven command from the project's root:

mvn -PautoInstallPackage clean install

This command places the acs-commons in the apps folder in your local version of AEM. (See A in the illustration at the beginning of this article.) 

Create an AEM application folder structure  

Create an AEM application folder structure that contains templates, components, and pages by using CRXDE Lite.  

CQAppSetup

 

The following describes each application folder:

  • application name: contains all of the resources that an application uses. The resources can be templates, pages, components, and so on.
  • components: contains components that your application uses.
  • page: contains page components. A page component is a script such as a JSP file.
  • global: contains global components that your application uses.
  • template: contains templates on which you base page components.
  • src: contains source code that comprises an OSGi component (this development article does not create an OSGi bundle using this folder).
  • install: contains a compiled OSGi bundles container.

To create an application folder structure:

  1. To view the CQ welcome page, enter the URL http://[host name]:[port] into a web browser. For example, http://localhost:4502.
  2. Select CRXDE Lite.
  3. Right-click the apps folder (or the parent folder), select Create, Create Folder.
  4. Enter the folder name into the Create Folder dialog box. Enter list.
  5. Repeat steps 1-4 for each folder specified in the previous illustration.
  6. Click the Save All button.

Note:

You have to click the Save All button when working in CRXDE Lite for the changes to be made.  

Create a template 

You can create a template by using CRXDE Lite. A CQ template enables you to define a consistent style for the pages in your application. A template comprises of nodes that specify the page structure. For more information about templates, see Templates.

To create a template, perform these tasks:

1. To view the CQ welcome page, enter the URL http://[host name]:[port] into a web browser. For example, http://localhost:4502.

2. Select CRXDE Lite.

3. Right-click the template folder (within your application), select Create, Create Template.

4. Enter the following information into the Create Template dialog box:

  • Label: The name of the template to create. Enter templateList.
  • Title: The title that is assigned to the template.
  • Description: The description that is assigned to the template.
  • Resource Type: The component's path that is assigned to the template and copied to implementing pages. Enter list/components/page/templateList.
  • Ranking: The order (ascending) in which this template will appear in relation to other templates. Setting this value to 1 ensures that the template appears first in the list.

5. Add a path to Allowed Paths. Click on the plus sign and enter the following value: /content(/.*)?.

6. Click Next for Allowed Parents.

7. Select OK on Allowed Children.

Create the page component based on the template  

Components are re-usable modules that implement specific application logic to render the content of your web site. You can think of a component as a collection of scripts (for example, JSPs, Java servlets, and so on) that completely realize a specific function. In order to realize this functionality, it is your responsibility as a CQ developer to create scripts that perform specific functionality. For more information about components, see Components.

By default, a component has at least one default script, identical to the name of the component. To create a render component, perform these tasks:

1. To view the CQ welcome page, enter the URL http://[host name]:[port] into a web browser. For example, http://localhost:4502.

2. Select CRXDE Lite.

3. Right-click /apps/list/components/page, then select Create, Create Component.

4. Enter the following information into the Create Component dialog box:

  • Label: The name of the component to create. Enter templateList.
  • Title: The title that is assigned to the component.
  • Description: The description that is assigned to the template.
  • Super Type: foundation/components/page (in AEM 6, you specify this value for page components. In previous versions of AEM, this was not rquired.)

5. Select Next for Advanced Component Settings and Allowed Parents.

6. Select OK on Allowed Children.

7. Open the templateWeb.jsp located at: /apps/list/components/page/templateList/templateList.jsp.

8. Enter the following HTML code.

<html>
<%@include file="/libs/foundation/global.jsp" %>
<cq:include script="/libs/wcm/core/components/init/init.jsp"/>
<body>
<h1>Here is where your AEM 6 custom xtype component will go</h1>
<cq:include path="par" resourceType="foundation/components/parsys" />
</body>
</html>

Create an AEM 6 component that uses a custom xtype

After you setup the AEM folder structure, create the AEM Touch UI component. Perform these tasks using CRXDE Lite:

1. Right click on /apps/list/components and then select New, Component.

2. Enter the following information into the Create Component dialog box:

  • Label: The name of the component to create. Enter definition-list2.
  • Title: The title that is assigned to the component. Enter definition-list2.
  • Description: The description that is assigned to the template. Enter definition-list2.
  • Super Resource Type: Enter foundation/components/parbase.
  • Group: The group in the side kick where the component appears. Enter General. (The definition-list2 component is located under the General heading in the Touch UI side rail. Also appears in General in the classic view sidekick.)
  • Allowed parents: Enter */*parsys.

3. Click Ok.

Add a dialog to the AEM Touch UI component  

A dialog lets an author click on the component in the Touch UI (or Classic UI) view during design time and enter values that are used by the component. The component created in this development article lets the AEM author enter text values, which are then displayed in the AEM web page. (See the illustration shown at the beginning of this development article.)

To add the dialog in this development article, copy the following node:

/apps/acs-commons/components/content/definition-list/dialog

Paste the dialog node to the following JCR location:

/apps/list/components/definition-list2

Once you are done, your AEM project resembles the following illustration. 

Dialog


Note:

In this development article, the dialog is copied from the other AEM project. However, you typcially build a component dialog using CRXDE lite. For information, see Creating your first Adobe Experience Manager custom xtype

The dialog for the definition-list2 component references a custom xtype named multifieldpanel.  This is referenced through the following node's xtype property: /apps/list/components/definition-list2/dialog/items/items/tab1/items/definitions/fieldConfig.

Note:

This dialog is based on a classic dialog which works in Touch UI. To use a custom xtype, you build a dialog using this manner. To learn how to build a Touch UI dialog, see Creating your first Adobe Experience Manager Touch UI component.

The custom xtype's implementation JS file is located here:

/apps/acs-commons/widgets/source/js/multipanel.js

This is part of the AEM project that you built and deployed in step one of this development article. The following code represents this JS file. 

CQ.Ext.ns("ACS.CQ");
/**
 * @class ACS.CQ.MultiFieldPanel
 * @extends CQ.form.Panel
 * <p>The MultiFieldPanel widget is a replacement for the normal multifield widget which
 * supports multiple structures in a single JCR property. It does this by storing a set of
 * key/value pairs serialized as a JSON object. The keys for each pair is defined by setting the
 * 'key' property on the field.</p>
 */
ACS.CQ.MultiFieldPanel = CQ.Ext.extend(CQ.Ext.Panel, {
    panelValue: '',

    /**
     * @constructor
     * Creates a new MultiFieldPanel.
     * @param {Object} config The config object
     */
    constructor: function(config){
        config = config || {};
        if (!config.layout) {
            config.layout = 'form';
            config.padding = '10px';
        }
        ACS.CQ.MultiFieldPanel.superclass.constructor.call(this, config);
    },

    initComponent: function() {
        ACS.CQ.MultiFieldPanel.superclass.initComponent.call(this);

        this.panelValue = new CQ.Ext.form.Hidden({
            name: this.name
        });

        this.add(this.panelValue);

        var dialog = this.findParentByType('dialog');

        dialog.on('beforesubmit', function(){
            var value = this.getValue();

            if (value){
                this.panelValue.setValue(value);
            }
        },this);
    },

    getValue: function() {
        var pData = {};

        this.items.each(function(i){
            if(i.xtype === "label" || i.xtype === "hidden" || !i.hasOwnProperty("key")){
                return;
            }

            pData[i.key] = i.getValue();
        });

        return $.isEmptyObject(pData) ? "" : JSON.stringify(pData);
    },

    setValue: function(value) {
        this.panelValue.setValue(value);

        var pData = JSON.parse(value);

        this.items.each(function(i){
            if(i.xtype === "label" || i.xtype === "hidden" || !i.hasOwnProperty("key")){
                return;
            }

            if(!pData[i.key]){
                return;
            }

            i.setValue(pData[i.key]);
        });
    },

    validate: function(){
        return true;
    },

    getName: function(){
        return this.name;
    }
});

CQ.Ext.reg("multifieldpanel", ACS.CQ.MultiFieldPanel);	

Note:

This JS script is located in a client library folder located at the following JCR location: /apps/acs-commons/widgets. Notice that the category property is cq:widgets. It's strongly recommended that you place custom xtypes in a cq:widgets client library folder for use in AEM 6, as shown in this development article. If a custom xtype is placed in a client library folder based on a custom category property (for example, myclientlib), it may not work in AEM 6 Touch UI. 

It can be in any of these categories:

  • cq.wcm.edit
  • cq.widgets
  • cq.security
  • cq.tagging
  • cq.cloudserviceconfigs
  • cq.dam.scene7
     

Add JavaScript code to the clientlib JS files

Add JavaScript logic to the definition-list2.jsp component's JSP file. All this component does is to display the values that are entered into the dialog on the AEM web page. It is important that you understand how to retrieve values that are entered into a component's dialog before building more advanced components.

Add the following application logic to the JSP file located at: /apps/list/components/definition-list2/definition-list2.jsp.

<%@include file="/libs/foundation/global.jsp" %>
<cq:includeClientLib categories="cq.widgets" />
<%@ taglib prefix="wcmmode" uri="http://www.adobe.com/consulting/acs-aem-commons/wcmmode" %><%
%><%@ taglib prefix="widgets" uri="http://www.adobe.com/consulting/acs-aem-commons/widgets" %><%
%><%@ taglib prefix="xss" uri="http://www.adobe.com/consulting/acs-aem-commons/xss" %><%
%><%@ taglib prefix="wcm" uri="http://www.adobe.com/consulting/acs-aem-commons/wcm" %>
<c:set var="definitions" value="${widgets:getMultiFieldPanelValues(resource, 'definitions')}"/>
<c:choose>
    <c:when test="${empty definitions}">
        <wcm:placeholder classNames="cq-dl-placeholder cq-block-placeholder"/>
    </c:when>
    <c:otherwise>
        <dl>
            <c:forEach items="${definitions}" var="definition">
                <dt>${xss:encodeForHTML(xssAPI, definition['term'])}</dt>
                <dd>${xss:encodeForHTML(xssAPI, definition['definition'])}</dt>
            </c:forEach>
        </dl>
    </c:otherwise>
</c:choose>

In this example, notice that the values:

 

<dt>${xss:encodeForHTML(xssAPI, definition['term'])}</dt>
<dd>${xss:encodeForHTML(xssAPI, definition['definition'])}</dt>

Lines up with the key property specified in these two JCR locations:

  1. /apps/list/components/definition-list2/dialog/items/items/tab1/items/definitions/fieldConfig/items/term
  2. /apps/list/components/definition-list2/dialog/items/items/tab1/items/definitions/fieldConfig/items/definition

This is how the values entered into the components dialog, which is based on a custom xtype, is displayed in the AEM web page.

 

Create an AEM web page that uses the defination-list2  component 

The final task is to create a site in the AEM Touch UI view that contains a page that is based on  templateList (the template created earlier in this development article). This AEM page lets you select the defination-list2 component that you just created from the AEM Touch UI side rail, as shown in the following illustration.

Site

Likewise, you can also use the defination-list2 component in the AEM classic view. In this situation, you drag the component from the CQ sidekick, as shown in the following illustration. 

 

classic2

To create an AEM web page that uses the Touch UI component, perform these tasks:

  1. Go to the AEM welcome page at http://[host name]:[port]; for example, http://localhost:4502.
  2. Select Sites.
  3. Select the + Icon in the web page. This create a new AEM page. 
  4. Select Create Page.
  5. Select templateList from the list of templates that appear. 
  6. Select Next.
  7. Specify the name of the page in the Title field.
  8. Select Create Page and open the new page. 
  9. Drag the defination-list2 compnent from the AEM side rail into the page. Double click on the component. Enter values into the dialog - which is based on a custom xtype. Once done, the values are displayed in the AEM web page.

Note:

If the AEM side panel is empty, populate the AEM side kick as described later in this section, when the AEM side kick is populated, the side rail is also populated with components. 

View the AEM page in Classic UI view and populate the AEM side kick

You can also view the page in AEM Classic UI view. To do so, select Classic View from the wheel icon in the AEM Page near the top, as shown in this illustration. 

ClassicView2

You will see the CQ sidekick and the defination-list2 component under the General category. You can drag and drop the defination-list2 component onto the CQ page.

If the CQ sidekick is empty, you can populate it by clicking the Design button located at the bottom of the sidekick. Next click the Edit button that appears and select General from the list of categories that appear as shown here.

General

To view the sidekick with the General category, click the down arrow icon that appears on the sidekick. Drag the defination-list2 component on the AEM web page. Double click on the component and you see the dialog that you created in this development article. 

See also

Congratulations, you have just created an AEM 6 Touch UI component that uses a custom xtype. Please refer to the AEM community page for other articles that discuss how to build AEM services/applications.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy