Hi Team
I have created a component where I have two multifield properties, and I want to convert the multifield and array format.
"items": {"jcr:primaryType": "nt:unstructured","item0": {"jcr:primaryType": "nt:unstructured","text": "Same as Permanent address","value": "same as permanent address","selected": "false"},"item1": {"jcr:primaryType": "nt:unstructured","text": "Others","value": "others","selected": "false"}},"mapping": {"jcr:primaryType": "nt:unstructured","item0": {"jcr:primaryType": "nt:unstructured","destination": "two","source": "one"},"item1": {"jcr:primaryType": "nt:unstructured","destination": "four","source": "three"},"item2": {"jcr:primaryType": "nt:unstructured","destination": "six","source": "five"}}
Here I have items and mapping multifields.
I would like to have structure like source: ["one","three","five"] and destination: ["two","four","six"]
Could anyone please help on this.
Is it possible to achieve it using htl or js.
Thanks and Regards
Prashanthi
Solved! Go to Solution.
Views
Replies
Total Likes
Hello @Prashardan ,
according to your structure and your requirement(Using HTL & JS) you can achieve this by this way.
In HTL you need to create the list value in a HTML attribute using Slightly loop.
<sly data-sly-use.cmpResource="${resource.path}/mapping"></sly>
<sly data-sly-set.destination=""/>
<sly data-sly-set.source=""/>
<sly data-sly-list.cmpItem="${cmpResource.listChildren}">
<sly data-sly-set.destination="${[destination, cmpItem.destination] @ join = ','}"/>
<sly data-sly-set.source="${[source, cmpItem.source] @ join = ','}"/>
</sly>
<div class="list-item" data-destination="${destination}" data-source="${source}"></div>
When you get the attribute value then get them from JS and create the list.
let destination = document.getElementsByClassName('list-item')[0].getAttribute('data-destination');
console.log(destination.split(',').filter(Boolean));
// Output: ["two", "four", "six"]
@Prashardan Please check below threads which has similar use cases:
Hello @Prashardan ,
according to your structure and your requirement(Using HTL & JS) you can achieve this by this way.
In HTL you need to create the list value in a HTML attribute using Slightly loop.
<sly data-sly-use.cmpResource="${resource.path}/mapping"></sly>
<sly data-sly-set.destination=""/>
<sly data-sly-set.source=""/>
<sly data-sly-list.cmpItem="${cmpResource.listChildren}">
<sly data-sly-set.destination="${[destination, cmpItem.destination] @ join = ','}"/>
<sly data-sly-set.source="${[source, cmpItem.source] @ join = ','}"/>
</sly>
<div class="list-item" data-destination="${destination}" data-source="${source}"></div>
When you get the attribute value then get them from JS and create the list.
let destination = document.getElementsByClassName('list-item')[0].getAttribute('data-destination');
console.log(destination.split(',').filter(Boolean));
// Output: ["two", "four", "six"]
Many thanks @Sady_Rifat
It worked perfectly. I have implemented my requirement completely with this one.
Many thanks once again.
@Prashardan , If it works according to your requirement, please mark this as the correct reply. So that, others get help from it.
@Prashardan I hope the AEM community has been helpful. We look forward to your return as either a learner or a contributor. The community grows with SMEs like you. Invite your AEM peers to contribute too. Happy AEM learning!
Views
Replies
Total Likes
@Prashardan We have the sling model, and it is advised to write the conversion and other business logic within it and then return it to the HTL.
@Model(adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class HelloWorldModel {
@PostConstruct
public void init() {
// Business logic to read the properties and then finally convert
}
}
You can also try out the javascript use api for the convertion and then return the result to HTL.
Hope this helps!
Thanks
Hi @Prashardan,
It is recommended to use sling models/service to write the business logic. You can implement it as follows
@Model(adaptables = Resource.class,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class MultiArrayModel {
@Getter
@Inject
private List<MultiArrayItem> mapping;
@Getter
private List<String> sourceArray = new ArrayList<>();
@Getter
private List<String> destinationArray = new ArrayList<>();
@PostConstruct
void init() {
mapping.forEach(item->{
sourceArray.add(item.getSource());
destinationArray.add(item.getDestination());
});
}
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class MultiArrayItem {
@Getter
@ValueMapValue
private String source;
@Getter
@ValueMapValue
private String destination;
}
The sightly will simply look like
Dialog
Output looks like:
Hope this helps!
Thanks