Create AEM multi module project using archtype 11
Create a new component with cq:dialog for Touch UI as shown below.
<?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="Country Details" 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"> <countries jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="Countries"> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./countries"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <countryName jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldLabel="Country Name" name="./countryName"/> <states jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/multifield" composite="{Boolean}true" fieldLabel="States"> <field jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container" name="./states"> <items jcr:primaryType="nt:unstructured"> <column jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/container"> <items jcr:primaryType="nt:unstructured"> <stateName jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldLabel="State Name" name="./stateName"/> <statePostal jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/textfield" fieldLabel="State Postal" name="./statePostal"/> <statePopulation jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/numberfield" fieldLabel="State Population" name="./statePopulation"/> <stateDensity jcr:primaryType="nt:unstructured" sling:resourceType="granite/ui/components/coral/foundation/form/select" fieldDescription="Select State Density" fieldLabel="State Density" name="./stateDensity"> <items jcr:primaryType="nt:unstructured"> <high jcr:primaryType="nt:unstructured" text="High" value="high"/> <medium jcr:primaryType="nt:unstructured" text="Medium" value="medium"/> <low jcr:primaryType="nt:unstructured" text="Low" value="low"/> </items> </stateDensity> </items> </column> </items> </field> </states> </items> </column> </items> </field> </countries> </items> </column> </items> </content> </jcr:root>
Now create slingmodels to get the authored values.
package com.aemquickstart.core.models; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Default; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.inject.Named; import java.util.ArrayList; import java.util.List; @Model(adaptables = Resource.class) public class CountriesModel { private final Logger logger = LoggerFactory.getLogger(getClass()); @Inject @Named("sling:resourceType") @Default(values = "No resourceType") protected String resourceType; @Inject @Optional private List<Resource> countries; private List<Country> countriesList = new ArrayList<>(); public List<Country> getCountriesList() { return countriesList; } public void setCountriesList(List<Country> countriesList) { this.countriesList = countriesList; } @PostConstruct protected void init() { logger.debug("In init of CountriesModel"); if (!countries.isEmpty()) { for (Resource resource : countries) { Country student = resource.adaptTo(Country.class); countriesList.add(student); } } } }
Country.java
package com.aemquickstart.core.models; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The type Country. */ @Model(adaptables = Resource.class) public class Country { private final Logger logger = LoggerFactory.getLogger(getClass()); @Inject @Optional private String stateName; @Inject @Optional private List<Resource> states; @Optional private List<State> stateList = new ArrayList<>(); public List<State> getStateList() { return stateList; } public String getStateName() { return stateName; } public void setStateName(String stateName) { this.stateName = stateName; } public void setStateList(List<State> stateList) { this.stateList = stateList; } @PostConstruct protected void init() { logger.debug("In init method of Country model."); if(!states.isEmpty()) { for (Resource resource : states) { State state = resource.adaptTo(State.class); stateList.add(state); } } } }
State.java
package com.aemquickstart.core.models; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.PostConstruct; import javax.inject.Inject; @Model(adaptables = Resource.class) public class State { private final Logger logger = LoggerFactory.getLogger(getClass()); @Inject @Optional private String stateDensity; @Inject @Optional private String statePopulation; @Inject @Optional private String stateName; @Inject @Optional private String statePostal; public String getStateDensity() { return stateDensity; } public void setStateDensity(String stateDensity) { this.stateDensity = stateDensity; } public String getStatePopulation() { return statePopulation; } public void setStatePopulation(String statePopulation) { this.statePopulation = statePopulation; } public String getStateName() { return stateName; } public void setStateName(String stateName) { this.stateName = stateName; } public String getStatePostal() { return statePostal; } public void setStatePostal(String statePostal) { this.statePostal = statePostal; } public Logger getLogger() { return logger; } @PostConstruct protected void init() { logger.debug("In init of State Model"); } }
Add below html code in CountryDetails.html
<div> <b>Countries Details</b> <br><br> <div data-sly-use.countryModel="com.aemquickstart.core.models.CountriesModel" data-sly-unwrap> <div data-sly-test="${!countryModel || wcmmode.edit}"> Add country and state details using component dialog </div> <div data-sly-test="${countryModel.countriesList}"> <div data-sly-list.country="${countryModel.countriesList}"> <div> <div>Country Name: ${country.countryName}</div> <br> <div data-sly-list.state="${country.stateList}" style="margin-left:40px"> <div>State No.: ${stateList.count}</b></div> <div>Name: ${state.stateName}</b></div> <div>Postal: ${state.statePostal}</div> <div>Population: ${state.statePopulation}</div> <div>Density: ${state.stateDensity}</div> <br> </div> </div> </div> </div> </div> </div>
Deploy code using below maven command.
mvn clean install -PautoInstallPackage
Author CountryDetails component in touch dialog.
Authored details are visible on the page.
This comment has been removed by the author.
ReplyDeleteThanks Kishore, This helped me a lot to learn Sling models well.
ReplyDeleteThank you Kishore for such a clear explanation.
ReplyDelete