Goal
Create a sample component dialog using nested composite coral 3 multifield - /libs/granite/ui/components/coral/foundation/form/multifield
Demo | Package Install | Github
Multifield Structure in CRX
Multifield in Dialog
Multifield Storage in CRX
Component Rendering
Solution
1) Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-coral3-nested-composite-multifield
2) Sample dialog with nested composite multifield /apps/eaem-coral3-nested-composite-multifield/sample-nested-composite-multifield/cq:dialog
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="nt:unstructured" jcr:title="64 Nested Composite Multi Field" sling:resourceType="cq/gui/components/authoring/dialog"> <content jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <products jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="Products"> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./products"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <product jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldDescription="Name of Product" fieldLabel="Product Name" name="./product"/> <components jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="Components"> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./components"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <component jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldDescription="Name of Component" fieldLabel="Component Name" name="./component"/> <compPath jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/pathbrowser" fieldDescription="Select Path" fieldLabel="Path" name="./compPath" rootPath="/content"/> <size jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/select" fieldDescription="Select Size" fieldLabel="Size" name="./size"> <items jcr:primaryType="nt:unstructured"> <def jcr:primaryType="nt:unstructured" text="Select Size" value=""/> <small jcr:primaryType="nt:unstructured" text="Small" value="small"/> <medium jcr:primaryType="nt:unstructured" text="Medium" value="medium"/> <large jcr:primaryType="nt:unstructured" text="Large" value="large"/> </items> </size> </items> </column> </items> </field> </components> </items> </column> </items> </field> </products> </items> </column> </items> </content> </jcr:root>
3) #17 composite=true is for outer composite multifield (./products) and #37 composite=true for inner composite multifield (./components)
4) Create file (nt:file) /apps/eaem-coral3-nested-composite-multifield/sample-nested-composite-multifield/helper.js, add the following code for reading stored nodes
"use strict"; use( ["/libs/wcm/foundation/components/utils/ResourceUtils.js","/libs/sightly/js/3rd-party/q.js" ], function(ResourceUtils, Q){ log.info("Rendering...."); var prodPromise = Q.defer(), company = {}, productsPath = granite.resource.path + "/products"; company.products = undefined; ResourceUtils.getResource(productsPath) .then(function (prodParent) { return prodParent.getChildren(); }) .then(function(products) { addProduct(products, 0); }); function addProduct(products, currIndex){ if(!company.products){ company.products = []; } if (currIndex >= products.length) { prodPromise.resolve(company); return; } var productRes = products[currIndex], properties = productRes.properties; var product = { path: productRes.path, name: properties["product"] }; ResourceUtils.getResource(productRes.path + "/components") .then(function (compParent) { return compParent.getChildren(); }) .then(function(components) { addComponent(product, components, 0); }); company.products.push(product); addProduct(products, (currIndex + 1)); } function addComponent(product, components, currIndex){ if(!product.components){ product.components = []; } if (currIndex >= components.length) { return; } var compRes = components[currIndex], properties = compRes.properties; var component = { path: compRes.path, name: properties.component, compPath: properties.compPath, size: properties.size }; product.components.push(component); addComponent(product, components, (currIndex + 1)); } return prodPromise.promise; } );
5) Create file (nt:file) /apps/eaem-coral3-nested-composite-multifield/sample-nested-composite-multifield/sample-nested-composite-multifield.html, add the following code for rendering data
<div> <b>64 Nested Composite Multifield</b> <div data-sly-use.company="helper.js" data-sly-unwrap> <div data-sly-test="${!company.products && wcmmode.edit}"> Add products using component dialog </div> <div data-sly-test="${company.products}"> <div data-sly-list.product="${company.products}"> <div> <div>${product.name}</div> <div data-sly-list.component="${product.components}" style="margin-left:40px"> <div><b>${component.name}</b></div> <div>${component.compPath}</div> <div>${component.size}</div> </div> </div> </div> </div> </div> </div>
could you please share sightly version for the same nested multifield
ReplyDeleteThanks for sharing the post, After creating the dialog and opening it again, it behaves slightly different and does not render the correct heirarchy when click on Add. Do you know the reason for it. I am using AEM6.3 with above dialog (Coral 3)
ReplyDeletehaving same issue, when click on outer Add-filed button, only inner multi-field showing up without the outer multi-field.
ReplyDeleteAEM6.3 and coral-3
Thanks for sharing this
ReplyDeleteWe have migrated to AEM 6.5.
ReplyDeleteWe are facing an issue while opening a Touch UI dialog with multifield developed as in this blog. The already authored fields are not rendering in dialog and also we are not able to edit the multifield
Below is the error we are getting in console
Uncaught RangeError: Maximum call stack size exceeded composite-multifield.min.js:14
We have latest ACS commons installed. Please suggest us to overcome this.