Article summary

Summary

Discusses the following points:

  • how to develop an Experience Manager component that uses multi-field.
  • how to develop a custom xtype using the Experience Manager widget API.
  • how to read the values entered into custom xtype controls.
  • how to add the custom xtype component to the sidekick. 

For information about building a more advanced AEM component that uses a custom xtype (along with other functionality such as Drag and Drop and a Rich Text Editor), see Creating AEM multifield components that support drag and drop and uses custom xtypes.

A special thank you to Pratistha Mukherjee, a member of the AEM Community, for helping to test this article to ensure it works. 

This article is meant to work in AEM Classic view. If you want to use it witin the AEM Touch UI View, see Using custom xtypes in Adobe Experience Manager 6 Touch UI

Digital Marketing Solution(s) Adobe Experience Manager (Adobe CQ)
Audience
Developer (beginner - intermediate)
Required Skills
Java, JavaScript, HTML
Tested On Adobe Experience Manager 5.5, 5.6, 6.x

Note:

You can download an AEM package that contains code and the OSGi bundle that are used in this article. Download the package and deploy using package manager. The purpose of this code is to show the community these concepts in action. That is, it's to illustrate how to write a custom xtype. This community code is for teaching purposes only and not meant to go into production as is.

You can view the sample community application by using the following URL: http://localhost:4502/cf#/content/xtype.html (assuming you deploy on author).

Download

Introduction

You can create an Adobe Experience Manager widget that is based on a custom xtype. A custom xtype can contain other AEM controls such as combo boxes, text boxes, and so on. Also, the xtype is used within a component's dialog within a panel. An AEM author enters values into the custom xtype that are used by the AEM component. You can develop the custom AEM component to use these values to meet your business requirements. In this article, the values are retrieved using application logic within the component's JSP file and written to an Experience Manager page.

You can place AEM controls within a custom xtype and then use JavaScript to control the behaviour of each control. That is, you can define custom functionality that is not available with the standard component. For example, you can define custom JavaScript application logic within an event handler and dynamically update other fields. For information, see Dynamically updating AEM custom xtype fields.

Creating custom xtypes is a method of extending AEM standard components. To create a custom xtype, you use the AEM widget API. For information, see CQ5 Widgets API Documentation

The following illustration shows the custom xtype that is created in this development article.

Custom2

This is an single tab component that displays a multi-type, where each multi-field displays a custom xtype. Each custom xtype contains two controls:

  • A drop-down control that lets a user select a value.
  • A text field that lets a user enter values.

This AEM custom component lets the user specify how many multi-field controls to display. A new multi-field control can be displayed by clicking the Add Item link. Likewise, a mutli-field can be removed by clicking the remove icon (the red circle that contains a white dash). 

Once a user enters values into the fields, the componet simply reads all the values and writes them out to the CQ web page, as shown in this illustration.

myxtype


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

projectFiles2
Section Description
A An AEM clientlibs folder that contains JS files that use the AEM Widget API to create applicaiton logic that creates a custom xtype.   
B JCR nodes that represent the component's dialog.  
C The component JSP file. You can use application logic to get the values that a user entered into dialog values.
D The template and page component that lets an author drag the component from the sidekick onto an AEM web page during design time.

This development article steps you through how to build an AEM component that uses a custom xtype. The custom xtype type comprises of drop-down control and a text field as shown in the previous  illustration. 

Create an application folder structure  

Create an 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 xtype.
  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 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 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 templateXtype.
  • 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 xtype/components/page/templateXtype.
  • 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 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 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/xtype/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 templateXtype.
  • Title: The title that is assigned to the component.
  • Description: The description that is assigned to the template.
  • Super Type: foundation/components/page 

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

6. Select OK on Allowed Children.

7. Open the templateXtype.jsp located at: /apps/xtype/components/page/templateXtype/templateXtype.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 the custom xtype component will go</h1>
<cq:include path="par" resourceType="foundation/components/parsys" />
</body>
</html>

Create a component that uses a custom xtype

After you setup the AEM folder structure, create the AEM component that uses a custom xtype. Perform these tasks using CRXDE Lite:

1. Right click on /apps/xtype/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 myxtype.
  • Title: The title that is assigned to the component. Enter myxtype.
  • Description: The description that is assigned to the template. Enter myxtype.
  • Super Resource Type: Enter foundation/components/parbase.
  • Group: The group in the side kick where the component appears. Enter General. (The myxtype component is located under the General heading in the sidekick.)
  • Allowed parents: Enter */parsys.

3. Click Ok.

Note:

The remaining part of this article talks about how to create the AEM component that uses a custom xtype.  

Add a dialog to the AEM custom component  

A dialog lets an author click on the component during design time and enter values that are used by the component. The component created in this development article is a single tab that displays controls defined by the custom xtype. The custom xtype contains a combo-box and a text field. (See the illustration shown at the beginning of this development article.)

The following illustration shows the JCR nodes that represent the dialog created in this section.  

mytype


To add a dialog to the component, perform these tasks:

  1. Select /apps/xtype/components/myxtype, right click and select Create, Create Dialog.
  2. In the Title field, enter myxtype.
  3. Click Ok.
  4. Delete all nodes under /apps/xtype/components/myxtype/dialog/.

Create the dialog tab

Create the first (and only) tab in the dialog titled Custom xtype Multi-Field. This dialog contains a multi-field control where each field contains two controls defined by the custom xtype. You can add a field by clicking Add Item. Likewise, you can remove a field by clicking the delete button. The following illustration shows this tab displaying two multi-fields.    

Custom2

To create the Custom xtype Multi-Field tab, perform these tasks:

1. Click on the following node: /apps/xtype/components/myxtype/dialog.

2. Right click and select Create, Create Node. Enter the following values:

  • Name: items
  • Type: cq:Widget

3. Select the /apps/xtype/components/myxtype/dialog/items node.

4. Add the following property to the items node.

Name Type Value Description
xtype String tabpanel Specifies the data type for the control. A tabpanel is a tab container that holds other tabs (one or more tabs).

5. Click on the following node: /apps/xtype/components/myxtype/dialog/items.

6. Right click and select Create, Create Node. Enter the following values:

  • Name: items
  • Type: cq:WidgetCollection

7. Click on the following node: /apps/xtype/components/myxtype/dialog/items/items.

8. Right click and select Create, Create Node. Enter the following values:

  • Name: first
  • Type: cq:Widget

9. Add the following properties to the first node.

Name Type Value Description
title String Custom xtype Multi-Field
The text that is displayed.
xtype String panel
Specifies the data type for this control. A panel holds other controls.

10. Click on the following node: /apps/xtype/components/myxtype/dialog/items/items/first.

11. Right click and select Create, Create Node. Enter the following values:

  • Name: items
  • Type: cq:WidgetCollections.

12. Click on the following node: /apps/xtype/components/myxtype/dialog/items/items/first/items.

13. Right click and select Create, Create Node. Enter the following values:

  • Name: multi
  • Type: cq:Widget

14. Add the following properties to the multi node.

Name Type Value Description
fieldLabel String Multi-Field The field label.
hideLabel Boolean true Specifies whether the label is hidden.
name String ./multi The name of the control.
xtype String multifield Specifies the data type. A multifield lets a user dynamically add additional fields to a dialog.

15. Click on the following node: /apps/xtype/components/myxtype/dialog/items/items/first/items/multi.

16. Right click and select Create, Create Node. Enter the following values:

  • Name: fieldConfig
  • Type: nt:unstructured

17. Add the following properties to the fieldConfig node.

Name Type Value Description
optionsProvider
String Ejst.x3.provideOptions2 Specifies the provider that populates the drop-down control in the custom xtype.  This value is implemented as a method in the exercise.js file. (This is shown later in this development article.)
xtype
String ejstcustom
Specifies the name of the custom xtype. A custom xtype is defined by using JavaScript. Before this is successful, you have to register the custom xtype. (This is shown later in this development article.)

Setup a CQ:ClientLibraryFolder node 

Create a cq:ClientLibraryFolder node to store JS files that define the custom xtype. The folllowing illustration shows the cq:ClientLibraryFolder node.

 

clientlibs

After you create the clientlibs node, add the following properties to it.

Name Type Value
dependencies   String[] cq.xtype
categories String[] xtype

The dependencies property informs CQ to include the JS files in the JSP that comprises the component. The categories property informs CQ which clientlibs must be included.

You have to a file to the clientlibs folder. The text file maps the JS files and is named js.txt. The following lists the content of the js.txt file.

#base=js

exercises.js
CustomWidget.js

To add the files to the ClientLibs folder, perform these tasks:

  1. Right-click /apps/xtype/components then select New, Node.
  2. Make sure that the node type is cq:ClientLibraryFolder and name the node clientlibs.
  3. Right click on clientlibs and select Properties. Add the two properties specified in the previous table to the node.
  4. Right-click /apps/xtype/components/clientlibs then select New, Folder. Name the folder JS. 
  5. Add two JS files to the JS folder named CustomWidget.js and exercises.js. (You add code to these JS files in the next step.)
  6. Add a TXT file to the clientlibs folder named js.txt. Add the content specified in this section.

Add JavaScript code to the clientlib JS files

Add JavaScript logic that uses the AEM Widget API to the JS files that you created in the clientlibs node:

  • CustomWidget.js: defines the custom xtype that is used in the dialog tab. The name of the custom xtype defined in this file is named ejstcustom..
  • exercises.js: defines JavaScript logic that populates the drop-down control in the custom xtype.

CustomWidget.js

To develop a custom xtype, you can use a compositeField object,  which is the base class for panel based, complex form fields which include one form field or a group of form fields. For information, see class CQ.form.CompositeField.

The component’s dialog references the custom xtype. The following file represents the CustomWidget.js file.

Ejst.CustomWidget = CQ.Ext.extend(CQ.form.CompositeField, {

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    hiddenField: null,

    /**
     * @private
     * @type CQ.Ext.form.ComboBox
     */
    allowField: null,

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    otherField: null,
    
    constructor: function(config) {
        config = config || { };
        var defaults = {
            "border": false,
            "layout": "table",
            "columns":2
        };
        config = CQ.Util.applyDefaults(config, defaults);
        Ejst.CustomWidget.superclass.constructor.call(this, config);
    },

    // overriding CQ.Ext.Component#initComponent
    initComponent: function() {
        Ejst.CustomWidget.superclass.initComponent.call(this);

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

        this.allowField = new CQ.form.Selection({
            type:"select",
            cls:"ejst-customwidget-1",
            listeners: {
                selectionchanged: {
                    scope:this,
                    fn: this.updateHidden
                }
            },
            optionsProvider: this.optionsProvider
        });
        this.add(this.allowField);

        this.otherField = new CQ.Ext.form.TextField({
            cls:"ejst-customwidget-2",
            listeners: {
                change: {
                    scope:this,
                    fn:this.updateHidden
                }
            }
        });
        this.add(this.otherField);

    },

    // overriding CQ.form.CompositeField#processPath
    processPath: function(path) {
        console.log("CustomWidget#processPath", path);
        this.allowField.processPath(path);
    },

    // overriding CQ.form.CompositeField#processRecord
    processRecord: function(record, path) {
        console.log("CustomWidget#processRecord", path, record);
        this.allowField.processRecord(record, path);
    },

    // overriding CQ.form.CompositeField#setValue
    setValue: function(value) {
        var parts = value.split("/");
        this.allowField.setValue(parts[0]);
        this.otherField.setValue(parts[1]);
        this.hiddenField.setValue(value);
    },

    // overriding CQ.form.CompositeField#getValue
    getValue: function() {
        return this.getRawValue();
    },

    // overriding CQ.form.CompositeField#getRawValue
    getRawValue: function() {
        if (!this.allowField) {
            return null;
        }
        return this.allowField.getValue() + "/" +
               this.otherField.getValue();
    },

    // private
    updateHidden: function() {
        this.hiddenField.setValue(this.getValue());
    }

});

// register xtype
CQ.Ext.reg('ejstcustom', Ejst.CustomWidget);


In this example, notice that this.allowField is an instance of CQ.form.Selection. This object corresponds to the drop-down control located on the custom xtype. To make this control a drop-down control, the type property is assigned the value select. For information, see CQ.form.Selection.

Likewise, this.otherField is an instance of CQ.Ext.form.TextField. This object corresponds to the text field control located in the custom xtype. For information, see CQ.Ext.form.TextField.  

The custom xtype is registered by invoking the CQ.Ext.reg method, as shown in this line of code.

// register xtype
CQ.Ext.reg("ejstcustom", Ejst.CustomWidget);

 

exercise.js

The exercises.js file contains application logic that populates the drop-down control. This code lines up with a property assigned in the component's dialog. The optionsProvider property that belongs to the fieldConfig node is assigned Ejst.x3.provideOptions2.  The Ejst.x3.provideOptions2 method returns data that is displayed in the drop-down control.  

var Ejst = {};

Ejst.toggleProperties = function(id, expand) {
    var box = CQ.Ext.get(id);
    var arrow = CQ.Ext.get(id + '-arrow');
    if (expand || !box.hasClass('open')) {
        box.addClass('open');
        arrow.update('&laquo;');
    } else {
        box.removeClass('open');
        arrow.update('&raquo;');
    }
};

Ejst.expandProperties = function(comp) {
    comp.refresh();
    var id = comp.path.substring(comp.path.lastIndexOf('/')+1); 
    Ejst.toggleProperties(id, true);
};


Ejst.x3 = {};

Ejst.x3.provideOptions2 = function(path, record) {
    // do something with the path or record
    return [{
        text:"Value1",
        value:"val1"
    },{
        text:"Value2",
        value:"val2"
    }];
};

myxtype.jsp file

The myxtype.jps file is the main JSP file for the myxtype component. Application logic in this JSP file retrieves the values entered into each field in the custom xtype that is displayed in the multi-field. Each custom xtype contains a drop-down and a text field. Therefore the application logic reads the values from each field.  For example, if there are five muti-fields and each displays a custom xtype (each xtype has a drop-down and text field), and a user enters values into all fields, there will be 10 values. All values are read by using the code in the myxtype.jsp file. 

The following code gets all values entered into the multi-field. The name of the multi-field is multi, as assigned to the name property that belongs to the multi node in the dialog. 

 

<% Node node = null;
    if(resource.adaptTo(Node.class)!=null)
    {

    node=resource.adaptTo(Node.class);

    PropertyIterator props=null;
    if (node.getProperties()!=null)
        props = node.getProperties();

        while (props.hasNext()) {
            Property prop = props.nextProperty();
            String name = prop.getName();
            //System.out.println("property -- "+name);
            String value=null;
            String[] linkFields =null;

                if (prop.getDefinition().isMultiple() && (name.equalsIgnoreCase("multi"))) {
                    StringBuffer buf = new StringBuffer();
                    //buf.append("Link Type : ");
                    Value[] values = prop.getValues();
                    for (int i = 0; i < values.length; i++) {
                        buf.append(i > 0 ? "," : "");
                        buf.append(values[i].getString());
                    }

                    value = buf.toString();
                    String[] tokens = value.split(",");

                    for (int i=0;i<tokens.length;i++) 
                        {
                            //System.out.println(" tokens "+tokens[i]);
                            linkFields = tokens[i].split("\\\\");
                            for (int k=0; k<linkFields.length; k++)
                                {
                                //System.out.println(" value of k "+ k + "    linkfield"  + linkFields[k] );
                                if (k==0){
                                    %> <b>Link Type:</b> <%= linkFields[k] %>,<% continue;}
                                if (k==1){
                                    %> <b> Link Text: </b><%= linkFields[k] %>,<%continue;}
                                if (k==2){
                                    %> <b>Link URL: </b><%= linkFields[k] %><br /><%continue;}
                                }
                        }
    
                }
                else {
                    if (name.equalsIgnoreCase("multi")){
                value = prop.getString();
                    linkFields = value.split("\\\\");
                            for (int k=0; k<linkFields.length; k++)
                                {
                                //System.out.println(" value of k "+ k + "    linkfield"  + linkFields[k] );
                                if (k==0){
                                    %> <b>Link Type:</b> <%= linkFields[k] %>,<% continue;}
                                if (k==1){
                                    %> <b> Link Text: </b><%= linkFields[k] %>,<%continue;}
                                if (k==2){
                                    %> <b>Link URL: </b><%= linkFields[k] %><br /><%continue;}
                                }

                    }
                }
        }
        %>

This application logic read the values entered into the drop-down and text fields locted in each multi-field. It writes out these values to the CQ web page. The following code represents the entire myxtype.jsp.

 

<%@include file="/libs/foundation/global.jsp"%>
<cq:includeClientLib categories="xtype" />

<%@ page import="com.day.cq.commons.Doctype,
                    com.day.cq.wcm.foundation.Image,
                    com.day.cq.wcm.api.components.DropTarget,
                    com.day.cq.wcm.api.components.EditConfig,
                    com.day.cq.wcm.commons.WCMUtils,
                    org.apache.jackrabbit.commons.JcrUtils"
                        %>
<br>
----------------------------------
<br>
<b>*** mytype component starts ***</b>
<br>


<br>
<b>Here are the values that the user entered into custom xtype controls:</b>
<br><br>
<% Node node = null;
    
//This app logic gets back all values the user entered into the custom xtype and
//writes out the values to the CQ web page - the number of fields is unknown since
//each custom xtype is located on a multi-field
if(resource.adaptTo(Node.class)!=null)
    {

    node=resource.adaptTo(Node.class);

    PropertyIterator props=null;
    if (node.getProperties()!=null)
        props = node.getProperties();

        while (props.hasNext()) {
            Property prop = props.nextProperty();
            String name = prop.getName();
            //System.out.println("property -- "+name);
            String value=null;
            String[] linkFields =null;

                if (prop.getDefinition().isMultiple() && (name.equalsIgnoreCase("multi"))) {
                    StringBuffer buf = new StringBuffer();
                   
                    //Get the values entered into the custom xtype values
                    Value[] values = prop.getValues();
                    for (int i = 0; i < values.length; i++) {
                        buf.append(i > 0 ? "," : "");
                        buf.append(values[i].getString());
                    }

                    value = buf.toString();
                    String[] tokens = value.split(",");

                    for (int i=0;i<tokens.length;i++) 
                        {
                            //System.out.println(" tokens "+tokens[i]);
                            linkFields = tokens[i].split("\\\\");
                            for (int k=0; k<linkFields.length; k++)
                                {
                                //System.out.println(" value of k "+ k + "    linkfield"  + linkFields[k] );
                                if (k==0){
                                    %> <b>Type:</b> <%= linkFields[k] %>,<% continue;}
                                if (k==1){
                                    %> <b>Text: </b><%= linkFields[k] %>,<%continue;}
                                if (k==2){
                                    %> <b>URL: </b><%= linkFields[k] %><br /><%continue;}
                                }
                        }
    
                }
                else {
                    if (name.equalsIgnoreCase("multi")){
                value = prop.getString();
                    linkFields = value.split("\\\\");
                            for (int k=0; k<linkFields.length; k++)
                                {
                                //System.out.println(" value of k "+ k + "    linkfield"  + linkFields[k] );
                                if (k==0){
                                    %> <b>Type:</b> <%= linkFields[k] %>,<% continue;}
                                if (k==1){
                                    %> <b>Text: </b><%= linkFields[k] %>,<%continue;}
                                if (k==2){
                                    %> <b>URL: </b><%= linkFields[k] %><br /><%continue;}
                                }
                            }
                    }
                }
        }
        %>
<br><b>**myxtype component ends**</b><br>
-------------------------------
<br>

Add the files to the project

  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. Double-click /apps/xtype/components/myxtype/myxtype.jsp.
  4. Replace the JSP code with the new code shown in this section.
  5. Add the code shown in this section to the two JS files in the ClientLibs folder.
  6. Click Save All. 

Create a web page that uses the custom xtype component 

The final task is to create a site that contains a page that is based on the templateXtype (the template created earlier in this development article). This page will let you select the myxtype component  that you just created from the sidekick, as shown in the following illustration.

site

  1. Go to the welcome page at http://[host name]:[port]; for example, http://localhost:4502.
  2. Select Websites.
  3. From the left hand pane, select Websites.
  4. Select New Page.
  5. Specify the title of the page in the Title field.
  6. Specify the name of the page in the Name field.
  7. Select templateXtype from the template list that appears. This value represents the template that is created in this development article. If you do not see it, then repeat the steps in this development article. For example, if you made a typing mistake when entering in path information, the template will not show up in the New Page dialog box.
  8. Open the new page that you created by double-clicking it in the right pane. The new page opens in a web browser. Drag the aemgrid component from the sidekick under the General category.
  9. Double click on the myxtype component. Enter values into the dialog. Once done, the values are displayed in the AEM web page.

Populate the SideKick

You will see the sidekick and the myxtype component under the General category. You can drag and drop the myxtype component onto the page.

If the 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 myxtype component on the AEM web page. Double click on the component and you see the dialog that you created in this development article. The dialog displays controls defined in the custom xtype.

If you open the dialog and click on the multi-field button and the custom xtype does not appear, check the message in the web browser console window. If it states: ejstcustom cannot be defined, this means that the JS file defined in the clientlibs folder is not loaded in the page. The CustomWidget.js file defines the ejscustom xtype. Make sure that the categories property that you defined on the clientlibs node appears in the <cq:includeClientLib categories="xtype" /> code defined in myxtype.jsp. These two values must match and is how the custom xtype is loaded in the dialog.

See also

Congratulations, you have just created an AEM 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