Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

SOLVED

Writing Sling Models for Nested Multifields.

Avatar

Level 2

How can I write a sling Model to display a nested multifield with an image field in one of the multifield?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

You can refer https://blogs.perficient.com/2018/08/24/using-sling-models-with-nested-composite-mulitifields-in-aem... , I used the similar approach to manage pathbrowser (to select image) , text area( for description) and text field(title).

View solution in original post

4 Replies

Avatar

Correct answer by
Community Advisor

You can refer https://blogs.perficient.com/2018/08/24/using-sling-models-with-nested-composite-mulitifields-in-aem... , I used the similar approach to manage pathbrowser (to select image) , text area( for description) and text field(title).

Avatar

Community Advisor

Sample code for nested multifields- 

 

1. Sling model -

     

package com.aem.demo.core.models;

import java.util.List;
import javax.inject.Inject;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.Model;

@Model(
	    adaptables = {Resource.class},
	    defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface CompaniesModel {
	@Inject
	  List<Company> getCompanies(); // the name `getCompanies` corresponds to the multifield name="./companies"
	  /**
	   * Company model
	   * has a name and a list of departments
	   */
	  @Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
	  interface Company {
	    @Inject
	    String getName();
	    @Inject
	    List<Department> getDepartments(); // the name `getDepartments` corresponds to the multifield name="./departments"
	  }
	  /**
	   * Department model
	   * has a name and a manager
	   */
	  @Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
	  interface Department {
	    @Inject
	    String getImage();
	    
	  }

}

 

2. .context.xml associated with cq:dialog

 

<?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="Companies"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        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">
                    <companies
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                        composite="{Boolean}true"
                        fieldDescription="Click 'Add Field' to add a new company.">
                        <field
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/coral/foundation/container"
                            name="./companies">
                            <items jcr:primaryType="nt:unstructured">
                                <name
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                    fieldLabel="Comp. Name"
                                    name="name"/>
                                <departments
                                    jcr:primaryType="nt:unstructured"
                                    sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
                                    composite="{Boolean}true"
                                    fieldDescription="Click 'Add Field' to add a new department."
                                    fieldLabel="Departments">
                                    <field
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/coral/foundation/container"
                                        name="./departments">
                                        <items jcr:primaryType="nt:unstructured">
                                            <image
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
                                                fieldLabel="Image"
                                                name="image"
                                                rootPath="/content/dam/we-retail/en/people"/>
                                        </items>
                                    </field>
                                </departments>
                            </items>
                        </field>
                    </companies>
                </items>
            </column>
        </items>
    </content>
</jcr:root>

 

3. htl code -

<sly data-sly-use.companiesModel="com.aem.demo.core.models.CompaniesModel"/>
<sly data-sly-test.empty="${!companiesModel.companies}" />
<div data-sly-test="${wcmmode.edit && empty}" class="cq-placeholder" data-emptytext="${component.title}"></div>
<sly data-sly-test="${!empty}">
  <div>
      <ul data-sly-list.company="${companiesModel.companies}">
        <li>${company.name}
          <ul data-sly-list.department="${company.departments}">
            <li>
               <img src="${department.image}" width="300" height="300"></br>
            </li>
          </ul>
        </li>
      </ul>
  </div>
</sly>

4.  Author's entries using touch ui dialog and rendered output -

DEBAL_DAS_0-1650791505603.pngDEBAL_DAS_1-1650791514359.pngDEBAL_DAS_2-1650791532184.png

DEBAL_DAS_3-1650791541797.png

 

Avatar

Community Advisor

Dear @Manasi29 

 

You can use list of class as mentioned below for filed injectors

@Model(adaptables = {Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface CompaniesModel {
  @Inject
  List<Names> getNames(); // `getNames` corresponds to the multifield name="./names"
  /**
   * Names model
   * has a name and a list of first names
   */
  @Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
  interface Names {
    @Inject
    String getFirstName();
  }
  /**
   * First Name model
   * 
   */
  @Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
  interface Firstname {
    @Inject
    String getName();
  }
}

Regards,

Santosh