Cascade Select Dropdown in AEM Component Dialog
Published: 2020-11-03 05:30:32

This tutorial demonstrates how to populate [CoralUI Select](https://helpx.adobe.com/experience-manager/6-5/sites/developing/using/reference-materials/coral-ui/coralui3/Coral.Select.html) dropdowns in an AEM component dialog from a JSON data source using JavaScript. For added complexity, we're cascading the dropdowns in multiple instances within a [Multifield](https://helpx.adobe.com/experience-manager/6-5/sites/developing/using/reference-materials/granite-ui/api/jcr_root/libs/granite/ui/components/coral/foundation/form/multifield/index.html) component.

### Component Dialog

Rather than create a new component, we're just going to modify the existing helloworld component that is included with the project.

In the helloworld dialog `.content.xml`, add the following component nodes after the existing text component node.

**1.** Heading component (optional)

```xml
<heading
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/heading"
    text="Cars"
    level="3"/>
```

**2.** Composite Multifield component

```xml
<cars
    jcr:primaryType="nt:unstructured"
    sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
    composite="{Boolean}true">
    <field
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/container"
        name="./cars">
        <items jcr:primaryType="nt:unstructured">
            <make
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/form/select"
                emptyText="Select a make"
                fieldLabel="Car"
                name="./make">
            </make>
            <model
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/coral/foundation/form/select"
                emptyText="Select a model"
                name="./model">
            </model>
        </items>
    </field>
</cars>
```
The Multifield needs to be composite to store the cars `jcr:content` as item nodes.

#### Cars Data

A endpoint that returns a JSON response could be used instead, but for this proof-of-concept we're just adding a static JSON file resource to the existing `clientlib-base`. Create the folders `resources/data` in `clientlib-base` and add this `cars.json` file to it. e.g.,

##### clientlib-base/resources/data/cars.json
```json
{
  "cars": [{
     "make": "Chevy",
      "models": ["Camaro Z28", "Camaro ZL1", "Chevelle SS 454",  "Nova SS"]
    },{
      "make": "Dodge",
      "models": ["Challenger", "Charger Daytona", "Dart 426 Hemi"]
    },{
      "make": "Ford",
      "models": ["Fairlane Torino GT", "Mustang Boss 429", "Mustang Mach 1", "Mustang Shelby GT500", "Talladega", "Torino Cobra"]
    }
  ]
}
```

#### Component Dialog JavaScript

To add JavaScript that will be used by our component dialog, we're going to create a `clientlib-edit` folder with a `jcr:primaryType` of `cq:ClientLibraryFolder` in our component folder. To ensure that the library is only loaded for authoring dialogs, it needs to have its category set to `cq.authoring.dialog`. Additionally, to use the `ClientLibraryProxyServlet` that allows us to modularize our client libraries under `/apps`, set the `allowProxy` property. For example,

##### helloworld/clientlib-edit/.content.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
          jcr:primaryType="cq:ClientLibraryFolder"
          allowProxy="{Boolean}true"
          categories="[cq.authoring.dialog]"
          dependencies="[cq.jquery]"/>
```

>   Note the `cq.jquery` dependency. This is for just a couple jQuery methods included in our `dialog.js` and since it is already being loaded by AEM for its authoring environment, there is no additional overhead. Most of the script is using vanilla JS for modern browsers. As for the couple of jQuery functions, they could be refactored to vanilla JS pretty easily.

For the `dialog.js` JavaScript that includes the Coral UI API object. Please continue to the original post at [jimfrenette.com/aem/components/dialog-coral-ui-select-cascade](https://jimfrenette.com/aem/components/dialog-coral-ui-select-cascade/)

{% youtube udidVJ4cn5k %}