Implementing Conditional Dialog Fields
Introduction
In Adobe Experience Manager (AEM), dialog boxes are powerful tools for content authors to configure components. They can be enhanced to offer conditional visibility of fields based on user selections. In this article, we will extend a previously created Profile component to conditionally display fields based on a dropdown selection.
Step 1: Modify the Dialog Box
- Open the Dialog XML File: In IntelliJ, navigate to the Profile component’s dialog file (
_cq_dialog/.content.xml
) under/ui.apps/src/main/content/jcr_root/apps/wknd/components/profile
. - Add a Conditional Field: Let’s assume we want to show an additional text field, “Specialization”, that only appears when “CSE” is selected in the “Engineering Major” dropdown.Inside the
<content>
node of your dialog XML, add the following:
<engineeringMajor
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Engineering Major"
name="./engineeringMajor">
<items jcr:primaryType="nt:unstructured">
<cse
jcr:primaryType="nt:unstructured"
text="CSE"
value="CSE"/>
<eee
jcr:primaryType="nt:unstructured"
text="EEE"
value="EEE"/>
<ece
jcr:primaryType="nt:unstructured"
text="ECE"
value="ECE"/>
<mech
jcr:primaryType="nt:unstructured"
text="MECH"
value="MECH"/>
</items>
<granite:data
jcr:primaryType="nt:unstructured"
cq-dialog-dropdown-showhide-target=".specialization-showhide"
/>
</engineeringMajor>
<specializationcontainer
granite:class="specialization-showhide"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<specialization
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Specialization"
name="./specialization"/>
</items>
<granite:data
jcr:primaryType="nt:unstructured"
cq-dialog-dropdown-showhide-targetvalue="CSE"/>
</specializationcontainer>
<engineeringMajor>
Element – The Dropdown
This element defines a dropdown for selecting an engineering major. It uses the granite:class="cq-dialog-dropdown-showhide"
attribute, which is likely linked to a JavaScript listener that triggers the show/hide functionality based on the selection. The dropdown has multiple options (CSE, EEE, ECE, MECH), each defined within the <items>
sub-element.
Dropdown Show/Hide Targeting
The <granite:data>
element within the <engineeringMajor>
element specifies a cq-dialog-dropdown-showhide-target
attribute. This attribute points to a CSS selector (.list-option-listfrom-showhide-target
) that identifies the container(s) to be shown or hidden based on the dropdown’s selection. This CSS selector is used to dynamically alter the visibility of the targeted container(s) in the dialog.
<specializationcontainer>
Element – The Conditional Container
This container is designed to hold the specialization text field. It’s initially hidden or shown based on the selection in the <engineeringMajor>
dropdown, as indicated by its granite:class="hide list-option-listfrom-showhide-target"
attribute. The hide
class likely makes the container hidden by default, and the list-option-listfrom-showhide-target
class associates it with the targeting mechanism established by the <engineeringMajor>
dropdown.
Interaction Logic
- When an author selects an option from the
<engineeringMajor>
dropdown, the JavaScript associated with thecq-dialog-dropdown-showhide
class checks the value of the selected option. - If the selected option matches the criteria defined (for example, if “CSE” is selected), the script then looks for elements with the class specified in the
cq-dialog-dropdown-showhide-target
attribute of the<granite:data>
element within the dropdown (list-option-listfrom-showhide-target
in this case). - Based on the selection, the script toggles the visibility of the
<specializationcontainer>
. In the provided code snippet, there’s an indication that the visibility might be specifically linked to selecting “CSE” due to theshowhidetargetvalue="CSE"
attribute within the<specializationcontainer>
‘s<granite:data>
element, although this direct linkage is not explicitly detailed in the snippet you provided. In typical implementations, this attribute would inform the JavaScript which specific value of the dropdown should trigger the container to show.
Step 2: Update the Sling Model
- Modify the Profile Java Class: Open your Profile Java class in IntelliJ. Add a new property to handle the “Specialization” field.
package com.adobe.aem.guides.wknd.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.apache.sling.models.annotations.injectorspecific.ChildResource;
import org.apache.sling.models.annotations.DefaultInjectionStrategy;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import javax.inject.Inject;
import java.util.List;
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class ProfileModel {
@ValueMapValue
private List<String> hobbies;
@ChildResource
private List<Experience> previousExperience;
@Inject
@Optional
private String specialization;
public List<Experience> getPreviousExperience() {
return previousExperience;
}
public List<String> getHobbies() {
return hobbies;
}
// Getter for specialization
public String getSpecialization() {
return specialization;
}
}
Step 3: Update the HTL File
- Modify the HTL File: In the component’s HTL file, use the Sling model properties to render the fields.
<img src="${properties.profilePicture}" alt="Profile Picture">
<h2>${properties.candidateName}</h2>
<p>Date of Birth: ${'dd-MM-yyyy' @ format=properties.dateOfBirth}</p>
<p>Gender: ${properties.gender}</p>
<p>Hobbies Listed Below:</p>
<div data-sly-use.profileModel="com.adobe.aem.guides.wknd.core.models.ProfileModel">
<!-- Existing fields here -->
<ul data-sly-list.hobby="${profileModel.hobbies}">
<li>${hobby}</li>
</ul>
<ul data-sly-list.exp="${profileModel.previousExperience}">
<li>${exp.companyName}</li>
</ul>
<p>Engineering Major: ${properties.engineeringMajor}</p>
<!-- Conditional field -->
<sly data-sly-test="${profileModel.engineeringMajor == 'CSE'}">
<p>Specialization: ${profileModel.specialization}</p>
</sly>
</div>
<sly>
: The<sly>
tag is used in HTL to denote a block of code that should not introduce additional elements into the final HTML output. It’s often used for encapsulating logic or control structures without affecting the layout or structure of the generated markup. In this context, the<sly>
tag is used to wrap a conditional statement and its associated output.data-sly-test
: This is an HTL attribute that performs a test. If the test evaluates totrue
, the content within the tag is processed and included in the output. If the test evaluates tofalse
, the content within the tag is ignored, and nothing is rendered for that block in the final HTML. The expression${profileModel.engineeringMajor == 'CSE'}
is the condition being tested.${profileModel.engineeringMajor == 'CSE'}
: This expression uses the${}
syntax to evaluate a variable or expression. Here, it checks if theengineeringMajor
property of aprofileModel
object equals the string'CSE'
. TheprofileModel
is likely a Java object exposed to the HTL script, containing data about a user’s profile, including their chosen engineering major.
<p>Specialization: ${profileModel.specialization}</p>
: This is the content that will be rendered if thedata-sly-test
condition evaluates totrue
. It displays a paragraph element containing the text “Specialization: ” followed by the value of thespecialization
property from theprofileModel
object. This implies that if the user’s selected engineering major is ‘CSE’, then and only then will the user’s specialization be displayed on the webpage.
Step 4: Deploy and Test
- Deploy Your Changes: Use Maven or your preferred deployment method to build and deploy your changes to AEM.
- Test in AEM: Open the AEM authoring interface, drag and drop the Profile component onto a page, and select “CSE” from the dropdown. The “Specialization” field should now appear.