Expand my Community achievements bar.

How to fetch a link using multifield component

Avatar

Level 6

I'm trying to fetch a link using multifield component but the link is not getting rendered on the page. I have used Sling Model for this

9 Replies

Avatar

Community Advisor

Hi @Sanjana12 

 

Can you elaborate? Are you getting the link from Author in a Multifield widget? And are you trying to fetch it in Sling Model so that you can return it to Frontend?

Avatar

Level 6
@Model(adaptables= Resource.class,defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class Website {

@Inject
@Named("multifield/.")
List<Social> details;

public List<Social> getDetails() {
return new ArrayList<>(details);
}
}

Avatar

Level 6
@Model(adaptables= Resource.class,defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class Social {


@Inject
String socialMedia;

@Inject
String socialMediaLink;


public String getSocialMedia() {
return socialMedia;
}

public String getGetSocialMediaLink() {
return socialMediaLink;
}
}

Avatar

Community Advisor

Hi @Sanjana12 ,

You can use it in the following way. 

In the component dialog if you are using Coral3 resource Types make sure to use the composite="{boolean}true". Please see the below dialog snippet

 

 

<bookdetailswithmap
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                                        composite="{Boolean}true"
                                        fieldDescription="Books Details"
                                        fieldLabel="Book Details"
                                        required="{Boolean}false">
                                        <field
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container"
                                            emptyText="Books Details"
                                            name="./bookdetailswithmap">
                                            <items jcr:primaryType="nt:unstructured">
                                                <book
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    emptyText="Book Name"
                                                    fieldLabel="Book Name"
                                                    name="./bookname"/>
                                                <subject
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    emptyText="Book Subject"
                                                    fieldLabel="Book Subject"
                                                    name="./booksubject"/>
                                                <published
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                    emptyText="Publish Year"
                                                    fieldLabel="Publish Year"
                                                    name="./publishyear"/>
                                            </items>
                                        </field>
                                    </bookdetailswithmap>

In the above code I am trying to fetch book details. Create your dialog in a similar way. 

 

 

Now in your Model, 

1. Create a list

2. Get the resource and get -> componentResource.getChild("bookdetailswithmap")

This will fetch the nodes created under the multifield. (Whenever a multifield will be added a new node will be created)

3. Once the nodes are fetched, create a Map and input values in the map as shown. In your case you will be added the String Value of the Link to the map.

4. Return the Map.

 

 

 

 @Override
    public List<Map<String, String>> getBookDetailsWithMap() {
        List<Map<String, String>> bookDetailsMap=new ArrayList<>();
        try {
            Resource bookDetail=componentResource.getChild("bookdetailswithmap");
            if(bookDetail!=null){
                for (Resource book : bookDetail.getChildren()) {
                    Map<String,String> bookMap=new HashMap<>();
                    bookMap.put("bookname",book.getValueMap().get("bookname",String.class));
                    bookMap.put("booksubject",book.getValueMap().get("booksubject",String.class));
                    bookMap.put("publishyear",book.getValueMap().get("publishyear",String.class));
                    bookDetailsMap.add(bookMap);
                }
            }
        }catch (Exception e){
            LOG.info("\n ERROR while getting Book Details {} ",e.getMessage());
        }
        LOG.info("\n SIZE {} ",bookDetailsMap.size());
        return bookDetailsMap;
    }


 

 

Sightly -> In sightly fetch the list and iterate over the map using data-sly-list as shown below.

<div data-sly-use.books="com.aem.geeks.core.models.AuthorBooks">
.
.
.
<div data-sly-list.item="${books.bookDetailsWithMap}">

        <p> Book : <b>${item.bookname} </b></p>
        <p> Subject : <b>${item.booksubject}</b> </p>
        <p> Publish : <b>${item.publishyear}</b> </p>
    </div>

Thanks

Avatar

Level 6
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/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="My Multifield"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<properties
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
sling:resourceType="granite/ui/components/coral/foundation/container"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">


<details
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="Details">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./multifield">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<socialMedia
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
emptyText="Social Media"
name="./socialMedia"/>
<socialMediaLink
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/pathbrowser"
emptyText="Social Media Links"

rootPath="/content"
name="./socialMediaLink"/>
</items>
</column>
</items>
</field>

</details>

</items>
</column>
</items>
</columns>
</items>
</properties>
</items>
</tabs>
</items>
</content>
</jcr:root>

Avatar

Level 6
<sly data-sly-use.model="com.whiteleaf.core.models.Website">
<ul data-sly-list.item= "${model.details}">
<li>${item.socialMedia @ context='html'}</li>
<li><a href="<${item.socialMediaLink}"></a></li>

</ul>
</sly>

Avatar

Community Advisor

Kindly check my above answer, you will have to fetch the Multifield nodes using Map in Sling Model.

Avatar

Level 6

I need a pathfield actually. How to render the link on the page using a pathfield?

Avatar

Community Advisor

Logic remains the same. Pathfield would be fetched and stored as a String in Sling Model. So you can leverage the same logic. Just get the pathfield value in a variable and put it in the Map.