Hello everyone,
I'm working on an AEM component and have configured a multifield dialog. My goal is to iterate over the items added in this multifield using HTL.
The data appears to be saving correctly in CRXDE Lite under the component's node in a structure like /path/to/component/tiles/item0, /path/to/component/tiles/item1, etc., with properties like itemTitle on each itemX node.
Here is the relevant part of my dialog XML:
<tiles
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Tiles"
fieldDescription="Click 'Add field' to add the details for a new tile.">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/fieldset"
name="./tiles">
<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">
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Title"
name="itemTitle"/>
<!-- Other fields would go here -->
</items>
</column>
</items>
</field>
</tiles>
However, I'm unable to get anything to render in my HTL file. I've tried various approaches, but nothing seems to work.
Can someone please provide the correct HTL syntax to iterate over these multifield items? I'm trying to access the itemTitle property for each one.
I'd prefer a solution that doesn't require a Sling Model like using ${properties}
Thank you in advance for any help!
Views
Replies
Total Likes
Hi @JulioRo,
Since you've used composite="{Boolean}true" in your multifield and saved each item as a child node (eg. item0, item1, ...), accessing it purely via HTL without a Sling Model becomes limited, but it's still possible using resource.getChildren.
Here’s how you can iterate over the child nodes of the multifield path (tiles) in your component's HTML file:
<ul data-sly-list.item="${resource.getChild('tiles').listChildren}">
<li>${item.getValueMap['itemTitle']}</li>
</ul>
However, as a best practice - my recommendation would be to go with Sling Model, here’s why Sling Models are preferred:
Cleaner HTL: Business logic (like sorting, filtering, transforming) can be handled in Java.
Better error handling: You can validate presence of fields and fallback defaults.
Reusable data access: A Sling Model can be reused across components or templates.
Unit testability: Logic in Sling Models can be unit tested, HTL can't.
Example (just for reference):
@Model(adaptables = Resource.class)
public class TileComponent {
@ValueMapValue
private String itemTitle;
// Getters...
}
Then in HTL:
<ul data-sly-list.item="${tileModel.tiles}">
<li>${item.itemTitle}</li>
</ul>
This isn’t working
<ul data-sly-list.item="${resource.getChild('tiles').listChildren}"> <li>${item.getValueMap['itemTitle']}</li> </ul>
I’m getting an error.
Views
Replies
Total Likes
Hi @JulioRo ,
Could you try below
Check if ${resource.getChild('tiles')} is not null
${resource.getChild('tiles').children}
<li>${item.valueMap.itemTitle}</li>
Views
Replies
Total Likes
Thank you guys but I already found the solution.
<sly data-sly-list.tiles="${resource.getChildren}">
<sly data-sly-list.tile="${tiles.getChildren}">
Handle items here
</sly>
</sly>
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies