Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

How to retrieve (and submit with a dialog) the existing subnodes of the dialog's node

Avatar

Level 1

I find myself having to adapt to a legacy implementation that, upon upgrading to 6.5.4 and coral3 multifield, has stopped working.

 

The current situation is the following:

aem_aarush_0-1601372852403.png

 

I have a container_component with a dialog made up of only one coral3 multifield, in which you can basically select how many instances of a contained_component you want to have inside the container_component.

Here is its dialog:

 

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" jcr:primaryType="nt:unstructured" jcr:title="Dialog name" sling:resourceType="cq/gui/components/authoring/dialog">
  <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container">
    <items jcr:primaryType="nt:unstructured">
      <columns jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns" margin="{Boolean}true">
        <items jcr:primaryType="nt:unstructured">
          <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container">
            <items jcr:primaryType="nt:unstructured">
              <columns jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="Columns">
                <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./items">
                  <items jcr:primaryType="nt:unstructured">
                    <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container">
                      <items jcr:primaryType="nt:unstructured">
                        <singleColumn jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/select" fieldLabel="Column" required="{Boolean}true" name="./sling:resourceType">
                          <items jcr:primaryType="nt:unstructured">
                            <default jcr:primaryType="nt:unstructured" value="/apps/path/to/contained_component" text="Basic Column" selected="{Boolean}true" />
                          </items>
                        </singleColumn>
                      </items>
                    </column>
                  </items>
                </field>
              </columns>
            </items>
          </column>
        </items>
      </columns>
    </items>
  </content>
</jcr:root>

 

 

The thing which is peculiar is, of course, the fact that the select sets the sling:resourceType of the item of the multifield to the value of a contained_component, so that, as shown in the above screenshot, all the items (item0, item1, etc.) below the container_component will be in fact configurable and of type contained_component.


So far so good.

After submitting the container_component dialog for the first time, you get as many contained_component as you specified in the multifield, and you can configure them with their own dialog, and their properties will be serialized under item0, item1, etc. of the main multifield and below.

 

E.g. in the below picture, item0 will be of sling:resourceType of contained_component and its properties, such as titleTarget and titleText, (and subnodes) will be created with its own dialog.

aem_aarush_1-1601373813010.png

 

The issue I have is that, while it is possible to edit the dialog of item0, item1, etc. (i.e. contained_components) as many times as you please, as soon as you modify the dialog of the container_component, for example to add or remove a field, and you resubmit the dialog, all the configurations of item0, item1, etc. are reset, and the contained_components are recreated anew.

 

This is probably because, upon submit, the main nodes (of the container_component) are deleted and recreated (sorry for the heavy editing):

aem_aarush_0-1601380362496.png

 

I did try to use add the property deleteHint, to the dialog of the container_component but the outcome was not desired one, because I still need to be able to add or delete the items of the multifield as I please.

 

So my question is: is there a way I can retrieve the nodes (and their configurations) - maybe using JS - that are currently in the JCR under item0, item1, etc. and, upon submitting the dialog of the container_component make sure they are added to the newly created nodes of item0,item1, etc.?
Much like in the last picture the highlighted sling:resourceType of item0 is modified?

 

I hope I was able to explain myself.
Thank you very much for you attention and the guidance you will be able to provide,

Aarush.

1 Accepted Solution

Avatar

Correct answer by
Level 8

Hi @aem_aarush 

Its not required to read config values in JS whenever we have nested multifield to resolve overriding issue. follow below steps, reset/overriding issue on submitting the container/parent component will be solved & property value will be stored/retrieved as expected.

 

there should be unique path name(refer below highlighted childCompPathName attribute) generated through code while including contained_component inside container_component & child/contained component node will be created parallel to parent/container component multifield node with this path name.

 

Sightly:

<sly data-sly-test="${resource.hasChildren}" data-sly-list.componentList="${resource.listChildren}">
<sly data-sly-test="${componentList.name == 'childCompList'}" data-sly-list="${componentList.listChildren}">
<sly data-sly-test.childCompPathName="${'childcomp{0}' @ format = itemList.index}">
<div data-sly-resource="${childCompPathName @ resourceType='/apps/path/to/contained_component'}"></div>
</sly>
</sly>
</sly>

 

Dialog:

<childCompList
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldDescription="Click 'Add field' to Add Child Component"
fieldLabel="Child Component">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./childCompList">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Configure title"
fieldLabel="Title"
name="./title"/>
</items>
</column>
</items>
</field>
</childCompList>

 

 

Data store node structure will be created as below:

 

child.PNG

 

 

Hope this helps!

 

-Manjunath

 

View solution in original post

3 Replies

Avatar

Correct answer by
Level 8

Hi @aem_aarush 

Its not required to read config values in JS whenever we have nested multifield to resolve overriding issue. follow below steps, reset/overriding issue on submitting the container/parent component will be solved & property value will be stored/retrieved as expected.

 

there should be unique path name(refer below highlighted childCompPathName attribute) generated through code while including contained_component inside container_component & child/contained component node will be created parallel to parent/container component multifield node with this path name.

 

Sightly:

<sly data-sly-test="${resource.hasChildren}" data-sly-list.componentList="${resource.listChildren}">
<sly data-sly-test="${componentList.name == 'childCompList'}" data-sly-list="${componentList.listChildren}">
<sly data-sly-test.childCompPathName="${'childcomp{0}' @ format = itemList.index}">
<div data-sly-resource="${childCompPathName @ resourceType='/apps/path/to/contained_component'}"></div>
</sly>
</sly>
</sly>

 

Dialog:

<childCompList
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldDescription="Click 'Add field' to Add Child Component"
fieldLabel="Child Component">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./childCompList">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Configure title"
fieldLabel="Title"
name="./title"/>
</items>
</column>
</items>
</field>
</childCompList>

 

 

Data store node structure will be created as below:

 

child.PNG

 

 

Hope this helps!

 

-Manjunath

 

Avatar

Level 1
Thank you, this helped me see the issue from a different perspective and solve the problem.