This article supports AEM 6.2 and below if you are looking for AEM 6.3 touch UI multifield control then I suggest you read this article AEM 6.3 Granite UI Coral 3 multifield component
In this article, I am going to explain to you how to build multifield control using TouchUI, building multifield control is not simple thing when it comes to touchUI, we have faced lot issues when we were working on AEM 6.0, but luckily the acs-commons provided custom multifield control so, for me it does not make sense to re-invent the wheel once again so I am going to explain how can we re-use acs commons multifield in our projects without re-inventing the wheel
The first thing which you need to do is download and install ACS Commons in your local development environment, then go to the crx/de/index.jsp and check the folders related to acs commons are created or not, once acs commons are installed then go to your component and add below fields,if you are familiar with XML then you can create dialog directly in dialog.XML file
<staticList jcr:primaryType="nt:unstructured" jcr:title="Static List" sling:resourceType="granite/ui/components/foundation/container"> <layout jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container"> <items jcr:primaryType="nt:unstructured"> <list jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/multifield" class="full-width" eaem-nested="" fieldDescription="Click '+' to add a new link" fieldLabel="links"> <layout jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns" method="absolute"/> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/fieldset" acs-commons-nested="NODE_STORE" name="./staticList"> <items jcr:primaryType="nt:unstructured"> <columns jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/container"> <items jcr:primaryType="nt:unstructured"> <linkUrl jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/pathbrowser" fieldDescription="Selecte link url" fieldLabel="Link Url" name="./linkUrl"/> <linkText jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/textfield" fieldDescription="Enter link text" fieldLabel="Link Text" name="./linkText"/> <linkTarget jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/select" fieldDescription="Please choose target type" fieldLabel="Target" name="./linkTarget"> <items jcr:primaryType="nt:unstructured"> <optionOne jcr:primaryType="nt:unstructured" text="New Tab" value="_blank"/> <optionTwo jcr:primaryType="nt:unstructured" text="New Window" value="_top"/> </items> </linkTarget> <screenReaderText jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/foundation/form/textfield" fieldDescription="Enter Screen Reader Text for link" fieldLabel="Screen Reader Text" name="./screenReaderText"/> </items> </columns> </items> </field> </list> </items> </column> </items> </staticList>
To create a custom multifield first create a node and add sling resource type to granite multifield widget “sling:resourceType=”granite/ui/components/foundation/form/multifield” , up to now nothing has changed, now what you need to do is add separate property to this multifield widget and the property is
eaem-nested=""
Once this is completed then the next step is, create a fieldset and add below property, the ACS Commons multifield JavaScript creates multifield control based on these properties, the NODE_STORE value creates new node for every record and assigns property’s to it
acs-commons-nested="NODE_STORE"
Then the remaining things are same you just need to create container and add fields which need to have appeared when you click on add new button
For the above XML the dialog will be rendered something like below if you face any issue with the width of fields then add below class for multifield node and all other fields, linkUrl, Title, screen readers text etc…
class = foundation-layout-util-maximized-alt long-label
Now, just add some records using multifield control and check the repository, the node structure will be created something like below
Now I suggest you to use below sling model code to read static list values, for more information on sling models and how it works check this link Sling Models
@Model(adaptables = Resource.class) public class List { public java.util.List<Link> links; @Inject private ResourceResolver resourceResolver; @Inject @Named("staticList") private Resource linksResource; @PostConstruct protected void init() { links = new ArrayList<Link>(); if (linksResource != null) { populateModel(links, linksResource); } } public static java.util.List<Link> populateModel( java.util.List<Link> array, Resource resource) { if (resource != null) { Iterator<Resource> linkResources = resource.listChildren(); while (linkResources.hasNext()) { Link link = linkResources.next().adaptTo(Link.class); if (link != null) array.add(link); } } return array; } }