I have a multifield component following this format
<?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="Awards List"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
type="-nav"/>
<items jcr:primaryType="nt:unstructured">
<awards
jcr:primaryType="nt:unstructured"
jcr:title="Awards Properties"
sling:resourceType="granite/ui/components/foundation/section">
<layout
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">
<description
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
fieldLabel="Description"
name="./description"/>
<awards
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Awards">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./awards">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<awardtype
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldDescription="Select Award Type"
fieldLabel="Award Type"
name="./type">
<items jcr:primaryType="nt:unstructured">
<gold
jcr:primaryType="nt:unstructured"
text="gold"
value="gold"/>
<silver
jcr:primaryType="nt:unstructured"
text="silver"
value="silver"/>
<bronze
jcr:primaryType="nt:unstructured"
text="bronze"
value="bronze"/>
<other
jcr:primaryType="nt:unstructured"
text="other"
value="other"/>
</items>
</awardtype>
<award
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Name of Award"
fieldLabel="Award Name"
name="./award"/>
</items>
</column>
</items>
</field>
</awards>
</items>
</column>
</items>
</awards>
</items>
</content>
</jcr:root>
And I'm trying to just output the contents of the multifield into a list. And I'm attempting to do so with
<ul data-sly-list="${properties.awards}">
<li>${item.type}</li>
</ul>
But it doesn't render anything. As a test I did
<ul data-sly-list="${[1,2,3,4]}">
<li>${item}</li>
</ul>
Which did work. Looking online I found resources like https://helpx.adobe.com/experience-manager/using/aem65_coral_resourcetypes.html#UseaDataSourceObjecttopopulateaSelectfield
But they seem to be using Java classes to generate the multifield and I'm hoping that's not necessary. I don't need any extra logic all I'm trying to do is display the values of the fields.
Is there something I'm doing wrong? Does using multifields require making a Java class to handle it?
EDIT: I've tried getting the content using a javascript object by having a js file with the contents
"use strict";
use(function () {
var description = granite.resource.properties["description"];
var awards = granite.resource.properties["awards"];
return {
description: description,
};
});
and using
<div data-sly-use.awardsObject="awardslist.js">
<p>
${awardsObject.description}
${awardsObject.awards}
</p>
</div>
But I can't get awards to return anything. I've tried stringifying the awards object to see if I get any data, but I get none.
It is probably because you are using a composite multifield (look at the property composite="{Boolean}true"
against the multifield) which generally handles the form content as composite and creates child nodes under the current component to hold the property values.
true to handle the form content value as composite.
Composite multifield supports nesting another multifield (composite or not). However, non-composite one doesn’t support nesting.
For example, given the name property of field is addresses, and the descendant fields have following name property values:
street1
street2
postcode
city/name
city/state
city/country/name
gps/lat
gps/long
it would save the following structure in the repository:
+ addresses + item0
- street1
- street2
- postcode
+ city
- name
- state
+ country
- name
+ gps
- lat
- long + item1
- street1
- street2
- postcode
+ city
- name
- state
+ country
- name
+ gps
- lat
- long
Since the properties
object only holds the properties of the current resource, ${properties.awards}
would be null and hence it doesn't display anything.
It would be easier to create either a Sling Model or Java / Javascript Use API class to get the list and then use it in the HTL file.
Sample JS Use API
"use strict";
use(function () {
var awards = resource.getChild("awards").listChildren();
return {
awards: awards,
};
});
Sample HTL code
<sly data-sly-use.children="children.js">
<ul data-sly-list.award="${children.awards}">
<li>${award.type}</li>
</ul>
<sly>
Kindly note that the properties
object, which is an instance of ValueMap only returns the properties of the current resource. Since the multifield values are stored as child resources, you need to access the child resource first before accessing its properties.