Multifield component in AEM TouchUI dialogs: the Zen Garden approach

03 May 2016
Tomasz Kaik
Frink_Cognifide_2016_HeaderImages_0117

ZenGarden_Stacked_rgb-fbRecently, a lot of the work within our site production accelerator, AEM Zen Garden has focused on adapting to changes and new features introduced in Adobe Experience Manager 6.1. One of the biggest challenges that we have encountered is the migration of components provided by Zen Garden to the new touch-optimized UI (TouchUI).  You can read more about this in our previous blog post, Building a Touch UI dialog with Zen Garden.

In this blog, I'd like to concentrate on the AEM dialog component,  Multifield, which allows an author to manage the collection of items.

Multifield component is available in AEM 6.1 as a GraniteUI component; the resource type is granite/ui/components/foundation/form/multifield. You can read about it in Granite UI 1.0 documentation - Multifield.

In the dialogs of AEM Zen Garden components we have 2 use cases for the Multifield widget:

  1. List of simple values - each item in the dialog is a single field (e.g. textfield) and all the values are stored in a single aggregate attribute (e. g. of type String[]).
  2. List of complex values (child nodes) - each item in the dialog can be configured as a set of fields (e.g. two text fields). Each of those items is stored in JCR as a seperate child node, with attributes corresponding to the configured field set.

Currently, the default GraniteUI Multifield component in AEM only supports the first of the presented use cases.

So, in AEM Zen Garden we have created our own custom extension of this component, which supports both use cases for a better authoring experience, and compatibility with the Multifield component available in ClassicUI. 

This custom Multifield widget can be referenced by the resource type zg/commons/components/widgets/multifield.


Multifield use case I - List of simple values

If we need a Multifield to manage a list of simple values, we can configure it using either the Granite Multifield component, or our custom extensions, because they need to be configured in the same way.

Here's an example configuration - a part of _cq_dialog.xml file of Form Select Field component from AEM Zen Garden: 

<options
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/foundation/form/multifield"
    fieldLabel="Options">
    <field
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/form/textfield"
        name="./options" />
</options>

(Note: sling:resourceType="granite/ui/components/foundation/form/multifield" could be replaced by sling:resourceType="zg/commons/components/widgets/multifield".)

This is what the Form Select Field component dialog looks like (Options section corresponds to the code block above):

form select field dialog

Below you can see a screenshot from the JCR repository browser, with values from Multifield stored in the attribute in the fifth row:

form select field JCR


Multifield use case II - List of complex values (child nodes)

This time we're going to take advantage of our extended Multifield component, which will allow us to store several properties for each of the sub-items of our component. To configure our custom Multifield for this use case, we need to: 

  • Add saveAsTree="true" attribute to the Multifield node, which is handled by our custom Javascript plugin,
  • Define all the fields, which will compose a single item of Multifield, inside a container node of resource type zg/commons/components/widgets/compositeSection.

Here's a part of _cq_dialog.xml file of Tabs component (which is one of Zen Garden components using described Multifield configuration): 

<names
    jcr:primaryType="nt:unstructured"
    sling:resourceType="zg/commons/components/widgets/multifield"
    fieldLabel="Names and titles"
    name="./names"
    saveAsTree="true">
    <field
        jcr:primaryType="nt:unstructured"
        sling:resourceType="zg/commons/components/widgets/compositeSection">
        <items jcr:primaryType="nt:unstructured">
            <name
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/foundation/form/textfield"
                fieldDescription="Displayed on tab navigation."
                fieldLabel="Name"
                name="name" />
            <title
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/foundation/form/textfield"
                fieldDescription="Displayed on opened tab."
                fieldLabel="Title"
                name="title" />
        </items>
    </field>
</names>

This is what the Tabs component dialog looks like:

tabs multi dialog

As you can see, each Multifield item consists of two text fields (Name and Title).

Below is a screenshot from the JCR repository browser, showing each item as a seperate node with proper attributes: 

tabs multi JCR


Use it yourself

In the link below you can download a package containing all sources required to implement our Multifield extension widget (CRX content package, Java sources and Javascript plugin).

Download link: AEM Zen Garden Multifield

Stay tuned for future articles relating to TouchUI in AEM Zen Garden, or check out our previous blog post, Building a Touch UI dialog with Zen Garden.

To find out more about AEM Zen Garden or to schedule a demo, please get in touch with sales@cognifide.com or come and see us at Adobe Summit at Excel London from 11th-12th May.

twitter img