In this article, I am going to explain to you how to build mulitifield control using Granite UI coral 3 components, If you are working on AEM 6.2 and want to build Touch UI based multifield control then this is not the right article for you I request you refer my other article “How to build multifield control using TouchUI“, this article covers OOTB multifield control which is part of AEM 6.3 and the main advantage of this is we do not need to use ACS touch UI multifield control
This article uses coral 3 components so, I suggest you refer my other article AEM 6.3 Granite UI: Coral 3 components for coral 3 based XML snippets
As part of this article, I am going to build simple list collection component, the authoring dialog of list collection component will have two fields link text and link path and the content author can author more than one record by just clicking on add icon button
<?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" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" jcr:primaryType="nt:unstructured" jcr:title="List Collection" sling:resourceType="cq/gui/components/authoring/dialog"> <content sling:resourceType="granite/ui/components/coral/foundation/container" jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <tabs sling:resourceType="granite/ui/components/coral/foundation/tabs" jcr:primaryType="nt:unstructured" maximized="{Boolean}true"> <items jcr:primaryType="nt:unstructured"> <Basic sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns" jcr:primaryType="nt:unstructured" margin="{Boolean}false" jcr:title="Basic"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <enterheadline sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldDescription="Please enter headline" fieldLabel="Enter Headline" jcr:primaryType="nt:unstructured" name="./headlineText" /> <multifieldcollection sling:resourceType="granite/ui/components/coral/foundation/form/multifield" fieldDescription="Click + to add a new page" fieldLabel="Multifield collection" jcr:primaryType="nt:unstructured" composite="{Boolean}true" name="./multiCol"> <field sling:resourceType="granite/ui/components/coral/foundation/container" jcr:primaryType="nt:unstructured" name="./items"> <items jcr:primaryType="nt:unstructured"> <linkurl sling:resourceType="granite/ui/components/coral/foundation/form/pathfield" fieldDescription="Select Link Path" fieldLabel="Link Url" jcr:primaryType="nt:unstructured" name="./linkUrl" /> <enterlinktext sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldDescription="Enter Link Text" fieldLabel="Enter link text" jcr:primaryType="nt:unstructured" name="./linkText" /> </items> </field> </multifieldcollection> </items> </column> </items> </Basic> </items> </tabs> </items> </content> </jcr:root>
Once building authoring dialog is completed, if you go and edit the component the multifield control should look like below
Once the content author completed his job, if you see the repository structure the content is stored something like below, under the parsys node every link is created as a separate node and added author entered values as properties
here, I am using sling models only for Link object but, if you want to see a full example on sling models then refer this article Building custom list collection component using sling models
package com.aem.toolkit.core.models; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; @Model(adaptables = Resource.class) public class Link { @Inject @Named("linkText") @Optional private String linkText; @Inject @Named("linkUrl") @Optional private String linkUrl; @PostConstruct protected void init() { } public String getTitle() { return linkText; } public String getUrl() { return linkUrl; } public void setTitle(String title) { linkText = title; } public void setUrl(String url) { linkUrl = url; ; } }
In the populateModel of ListCollectionHandler class, I am iterating all the child nodes and populating List collection
package com.aem.toolkit.core; import java.util.ArrayList; import java.util.Iterator; import org.apache.sling.api.resource.Resource; import com.adobe.cq.sightly.WCMUsePojo; import com.aem.toolkit.core.models.Link; public class ListCollection extends WCMUsePojo { public static java.util.List<Link> links; public java.util.List<Link> getLinks() { Resource childResource = getResource().getChild("items"); if (childResource != null) { links = populateModel(childResource); } return links; } public static java.util.List<Link> populateModel(Resource resource) { links = new ArrayList<Link>(); if (resource != null) { Iterator<Resource> linkResources = resource.listChildren(); while (linkResources.hasNext()) { Link link = linkResources.next().adaptTo(Link.class); if (link != null) links.add(link); } } return links; } @Override public void activate() throws Exception { } }
Sightly Code
Use the below sightly code to iterate the collection and render it on the page
<sly data-sly-use.listUse="com.aem.toolkit.core.ListCollection"> <ul data-sly-list="${listUse.links}"> <li><a href="${item.url}">${item.title}</a></li> </ul> </sly>
Download Code
[sociallocker] click here to download [/sociallocker]
nice explanation
I like the content – but letting the package be downloaded would be more helpful.
hello, how set max, min item in multifield ?
There is no OOTB functionality for this, you need to either write custom script or use ACS commons multifield
I have question for you, please support me. I look name=”./multiCol” var in multifield is unused. Why you add it ???
Nice Article
I m having a doubt where to keep the multifields xml code??? can someone help me
in content.xml
Very nice post. I tried couple of examples for multifields , This is the only one which worked.