Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Mutltifield to array in AEM Component

Avatar

Level 4

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

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

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"]

View solution in original post

7 Replies

Avatar

Correct answer by
Community Advisor

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"]

Avatar

Level 4

Many thanks @Sady_Rifat 
It worked perfectly. I have implemented my requirement completely with this one. 

Many thanks once again.

Avatar

Community Advisor

@Prashardan , If it works according to your requirement, please mark this as the correct reply. So that, others get help from it.

Avatar

Administrator

@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!



Kautuk Sahni

Avatar

Community Advisor

@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

 

Avatar

Community Advisor

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

madhurmadan2296_0-1681321834530.png

Dialog

madhurmadan2296_1-1681321873100.png

Output looks like:

madhurmadan2296_2-1681321958004.png


Hope this helps!

Thanks