May 19, 2020
Estimated Post Reading Time ~

Create a Multifield in Multifield without any custom code

Here's a plug and play solution built by chaining adobe's multifield xtype with a couple of open-source widgets.

Problem: Adobe's multiplied solution doesn't work with composite values. It stores the value as a String if only one value is configured and as a String[] if multiple values are configured. A common workaround to overcome this creates a custom composite field that concatenates the individual fields of a composite field into a single string with a delimiter (http://stackoverflow.com/questions/26290908/multifield-component-issue/26294172 ). This workaround fails when you want to have a varying number of composite fields with multifield inside the composite field. A common requirement while creating listing components such as mega menus and accordions. A lot of guys end up dynamically including parsys for every menu column or accordion block. The ideal solution would be to have a multifield in multifield (can be a little confusing for the author, but can be dealt with authoring guide and pointers in the dialog )

Solution: Use three widgets to create the multifield in multifield effect.
1) Multi composite - xtype that stores each multifield entry as a child node with the fields as properties. [Developed by Citytech inc]

2) Multifieldpanel - xtype that stores a multifield as an array of json objects where each field is a property of the json object. [Developed by ACS]

3) Multifield - the out of box multifield xtype.

The fix:  multicomposite  ( outer multifield )
                 |-fieldConfigs
                         |- field A (let's say a textfield, for the menu's column name)
                         |- field B (a pathfield to configure the link for the column name )
                         |- field C (multifield, the inner multifield to hold sub-menu entries)
                                  |-fieldConfig - xtype : multifieldpanel
                                        |- field Ca (textfield to hold title)
                                        |- field Cb (pathfield for the link)

Dialog  JSON -
{
matchBaseName: false,
xtype: "multicompositefield",
name: "./menu",
hideLabel: true,
jcr:primaryType: "cq:Widget",
fieldDescription: " click + to add menu column",
fieldConfigs:
{
jcr:primaryType: "cq:WidgetCollection",
name:
{
width: "500",
fieldLabel: "Name",
xtype: "textfield",
allowBalnk: true,
name: "title",
fieldLabel: "Link Title",
jcr:primaryType: "cq:Widget",
},
link:
{
xtype: "pathfield",
fieldLabel: "Link",
name: "link",
jcr:primaryType: "cq:Widget"
},
submenu:
{
xtype: "multifield",
title: "submenu",
fieldLabel: "Submenu",
name: "submenu",
collapsible: true,
jcr:primaryType: "cq:Widget",
fieldDescription: "Click + to add sub menu entry",
fieldConfig:
{
xtype: "multifieldpanel",
hideLabel: false,
jcr:primaryType: "cq:Widget",
items:
{
jcr:primaryType: "cq:WidgetCollection",
title:
{
key: "title",
xtype: "textfield",
fieldLabel: "Link Title",
jcr:primaryType: "cq:Widget"
},
link:
{
key: "link",
fieldLabel: "Link",
xtype: "pathfield",
jcr:primaryType: "cq:Widget"
}
}
}
}
}
}       

The data is stored in the following format :
{
jcr:primaryType: "nt:unstructured",
menu:
{
jcr:primaryType: "nt:unstructured",
item_1:
{
submenu:
[
"{"title":"Link 1","link":"http://cq5tutorials.blogspot.in"}",
"{"title":"Link 2","link":"http://cq5tutorials.blogspot.in"}"
],
title: "Main Menu Item 1",
jcr:primaryType: "nt:unstructured",
link: "http://cq5tutorials.blogspot.in"
},
item_2:
{
submenu:
[
"{"title":"Sub menu 1","link":"http://cq5tutorials.blogspot.in"}",
"{"title":"Sub menu 2","link":"http://cq5tutorials.blogspot.in"}"
],
title: "Main Menu item 2",
jcr:primaryType: "nt:unstructured",
link: "http://cq5tutorials.blogspot.in"
}
}
}

Notice that the inner multifield (submenu) is stored as an array of json strings. There is a utility in ACS code to read entries from this: http://adobe-consulting-services.github.io/acs-aem-commons/features/widgets.html

Few Drawbacks:
1) This xtype works only when it's on the first tab (or the tab that's active on dialog load ) of the dialog. Multifield doesn't handle all the extjs events like the rest of the widgets, as a result, the inner panels don't get rendered if the widget is not visible on load. Should not cause an issue as long as it's on the first tab of the dialog

2) The xtypes involved do not fire all events like the basic widgets, ex: beforeloadcontent. This can be a problem when you want to write a few custom listeners. If you know your way around extjs, this can still be accomplished by leveraging other events like the before add.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.