Lessons
  Menu

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

  1. 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.
  2. 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 the cq-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 the showhidetargetvalue="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

  1. 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

  1. 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 to true, the content within the tag is processed and included in the output. If the test evaluates to false, 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 the engineeringMajor property of a profileModel object equals the string 'CSE'. The profileModel 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 the data-sly-test condition evaluates to true. It displays a paragraph element containing the text “Specialization: ” followed by the value of the specialization property from the profileModel 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

  1. Deploy Your Changes: Use Maven or your preferred deployment method to build and deploy your changes to AEM.
  2. 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.