Expand my Community achievements bar.

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

Level 7

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