> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# Component Dialogs

## 1. Basic Dialog Structure

On Touch UI, all dialogs follow a strict nested XML structure built using Granite UI libraries. Below is the basic skeleton:

```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"
          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
          xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
          xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
          jcr:primaryType="nt:unstructured"
          jcr:title="Component Name"
          sling:resourceType="cq/gui/components/authoring/dialog">
    <content jcr:primaryType="nt:unstructured"
             sling:resourceType="granite/ui/components/coral/foundation/container">
        <items jcr:primaryType="nt:unstructured">
            <!-- Declare Tabs or Fields here -->
        </items>
    </content>
</jcr:root>
```

This file must be located at `_cq_dialog/.content.xml` inside the component directory.

To understand data storage mechanics, consider the interaction flow between UI and JCR:

```mermaid
sequenceDiagram
    participant Author as Content Author
    participant Dialog as "Touch UI Dialog\n(Granite UI)"
    participant Servlet as Sling POST Servlet
    participant JCR as "JCR Repository\n(Content Node)"

    Author->>Dialog: Enter content & Click "Save"
    Dialog->>Servlet: Send HTTP POST (mapped via name attribute)
    Servlet->>JCR: Write properties to current Node
    JCR-->>Servlet: Success response
    Servlet-->>Dialog: Reload Component UI with new data
```

## 2. Core Field Types (Common Widgets)

Below are common Granite UI field types (widgets), serving as building blocks for Dialogs.

### Textfield (Single-line Text)

```xml
<title jcr:primaryType="nt:unstructured"
       sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
       fieldLabel="Title"
       fieldDescription="Enter title for component"
       name="./title"
       required="{Boolean}true"
       maxlength="100"/>
```

### Textarea (Multi-line Text)

```xml
<description jcr:primaryType="nt:unstructured"
             sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
             fieldLabel="Description"
             name="./description"
             rows="5"/>
```

### Rich Text Editor (RTE)

```xml
<richText jcr:primaryType="nt:unstructured"
          sling:resourceType="cq/gui/components/authoring/dialog/richtext"
          fieldLabel="Content"
          name="./text"
          useFixedInlineToolbar="{Boolean}true"/>
```

### Number Field

```xml
<count jcr:primaryType="nt:unstructured"
       sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
       fieldLabel="Quantity"
       name="./count"
       min="{Long}1" max="{Long}100" step="{Long}1" value="{Long}10"/>
```

### Checkbox

```xml
<featured jcr:primaryType="nt:unstructured"
          sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
          text="Featured"
          name="./featured"
          value="{Boolean}true"/>
```

### Select Dropdown

```xml
<alignment jcr:primaryType="nt:unstructured"
           sling:resourceType="granite/ui/components/coral/foundation/form/select"
           fieldLabel="Alignment"
           name="./alignment">
    <items jcr:primaryType="nt:unstructured">
        <left jcr:primaryType="nt:unstructured" text="Left" value="left" selected="{Boolean}true"/>
        <center jcr:primaryType="nt:unstructured" text="Center" value="center"/>
        <right jcr:primaryType="nt:unstructured" text="Right" value="right"/>
    </items>
</alignment>
```

### Path Browser (Select Page or Asset)

```xml
<linkPath jcr:primaryType="nt:unstructured"
          sling:resourceType="cq/gui/components/coral/common/form/pagefield"
          fieldLabel="Path"
          fieldDescription="Select a page"
          name="./linkPath"
          rootPath="/content"/>
```

**`filter` Parameter Table:**

| `filter` Value     | Visibility Scope                              |
| ------------------ | --------------------------------------------- |
| `hierarchyNotFile` | Display Page structures only (exclude Assets) |
| `nosystem`         | Hide system paths                             |
| _(unspecified)_    | Display all paths                             |

### Image Upload

```xml
<file jcr:primaryType="nt:unstructured"
       sling:resourceType="cq/gui/components/authoring/dialog/fileupload"
       fieldLabel="Image"
       name="./file"
       fileNameParameter="./fileName"
       fileReferenceParameter="./fileReference"
       mimeTypes="[image/gif,image/jpeg,image/png,image/tiff,image/svg+xml]"/>
```

### Hidden Field

```xml
<componentType jcr:primaryType="nt:unstructured"
               sling:resourceType="granite/ui/components/coral/foundation/form/hidden"
               name="./componentType"
               value="customHero"/>
```

### Date Picker & Color Picker

```xml
<eventDate jcr:primaryType="nt:unstructured"
           sling:resourceType="granite/ui/components/coral/foundation/form/datepicker"
           fieldLabel="Event Date"
           name="./eventDate"
           type="datetime"/>

<bgColor jcr:primaryType="nt:unstructured"
         sling:resourceType="granite/ui/components/coral/foundation/form/colorpicker"
         fieldLabel="Background Color"
         name="./bgColor"/>
```

## 3. UI Organization using Tabs

For complex components, grouping fields into Tabs optimizes Authoring experience.

```xml
<tabs jcr:primaryType="nt:unstructured"
      sling:resourceType="granite/ui/components/coral/foundation/tabs"
      maximized="{Boolean}true">
    <items jcr:primaryType="nt:unstructured">
        <contentTab jcr:primaryType="nt:unstructured"
                    jcr:title="Content"
                    sling:resourceType="granite/ui/components/coral/foundation/container">
            <items jcr:primaryType="nt:unstructured">
                <!-- Content fields -->
            </items>
        </contentTab>
        <styleTab jcr:primaryType="nt:unstructured"
                  jcr:title="Style"
                  sling:resourceType="granite/ui/components/coral/foundation/container">
            <items jcr:primaryType="nt:unstructured">
                <!-- Style fields -->
            </items>
        </styleTab>
    </items>
</tabs>
```

**Standard Tab Division Pattern:**

| Tab          | Typical Fields                                                     |
| ------------ | ------------------------------------------------------------------ |
| **Content**  | Title, text, images (Core content).                                |
| **Style**    | Alignment, colors, size (Visual styling configuration).            |
| **Advanced** | HTML ID, CSS class, Accessibility attributes (Technical settings). |

## 4. Multifield Mechanics (Data Arrays)

Multifield allows authors to generate repeating field groups (e.g., Carousel Slides, Link Lists).

The key attribute is `composite="{Boolean}true"`. When enabled, AEM saves each multifield item as an independent **child node** containing its own properties. Without this attribute, data is saved as a String Array (applicable only for multifields containing a single Textfield).

```xml
<links jcr:primaryType="nt:unstructured"
       sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
       fieldLabel="Link List"
       composite="{Boolean}true">
    <field jcr:primaryType="nt:unstructured"
           sling:resourceType="granite/ui/components/coral/foundation/container"
           name="./links">
        <items jcr:primaryType="nt:unstructured">
            <label jcr:primaryType="nt:unstructured"
                   sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                   fieldLabel="Label" name="./label" required="{Boolean}true"/>
            <url jcr:primaryType="nt:unstructured"
                 sling:resourceType="cq/gui/components/coral/common/form/pagefield"
                 fieldLabel="URL" name="./url" required="{Boolean}true"/>
            <openInNewTab jcr:primaryType="nt:unstructured"
                          sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
                          text="Open in new tab" name="./openInNewTab" value="{Boolean}true"/>
        </items>
    </field>
</links>
```

JCR structure when using `composite=true`:

```mermaid
graph TD
    A["Component Node: /content/.../hero"] -->|name='./links' attribute| B["Folder: links"]
    B --> C["Child Node: item0"]
    B --> D["Child Node: item1"]
    C --> C1["label = 'Home'"]
    C --> C2["url = '/content/home'"]
    D --> D1["label = 'About'"]
    D --> D2["url = '/content/about'"]
```

## 5. Reading Values via Sling Models

When configuring Image Upload with `fileReferenceParameter="./fileReference"`, the selected DAM Asset path is saved as a String property.

In Sling Models, map this value using `@ValueMapValue`:

```java
@Model(adaptables = Resource.class)
public class HeroModel {

    @ValueMapValue
    private String fileReference; // DAM Path, e.g. "/content/dam/mysite/hero.jpg"

    public String getFileReference() {
        return fileReference;
    }
}
```

## 6. Understanding the `name` Attribute

The `name` attribute determines the exact JCR location where data will be persisted:

| `name` Syntax         | Storage Location in JCR                                      |
| --------------------- | ------------------------------------------------------------ |
| `./title`             | Directly on component content node (property named `title`). |
| `./jcr:title`         | Directly on content node (using standard `jcr` namespace).   |
| `./links/item0/label` | Nested inside sub-node `links/item0`.                        |

The `./` prefix specifies a relative path relative to the active content resource being edited.

## 7. Comprehensive Structure: Hero Component Dialog

Below is reference XML source code for a Hero banner dialog including column layout, tabs, and full field types:

```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"
          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
          xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
          xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
          jcr:primaryType="nt:unstructured"
          jcr:title="Hero Component"
          sling:resourceType="cq/gui/components/authoring/dialog">
    <content jcr:primaryType="nt:unstructured"
             sling:resourceType="granite/ui/components/coral/foundation/container">
        <items jcr:primaryType="nt:unstructured">
            <tabs jcr:primaryType="nt:unstructured"
                  sling:resourceType="granite/ui/components/coral/foundation/tabs"
                  maximized="{Boolean}true">
                <items jcr:primaryType="nt:unstructured">
                    <!-- Content Tab -->
                    <contentTab jcr:primaryType="nt:unstructured"
                                jcr:title="Content"
                                sling:resourceType="granite/ui/components/coral/foundation/container"
                                margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <columns jcr:primaryType="nt:unstructured"
                                     sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                     margin="{Boolean}true">
                                <items jcr:primaryType="nt:unstructured">
                                    <column jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container">
                                        <items jcr:primaryType="nt:unstructured">
                                            <heading jcr:primaryType="nt:unstructured"
                                                     sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                     fieldLabel="Title" name="./heading" required="{Boolean}true"/>
                                            <subheading jcr:primaryType="nt:unstructured"
                                                        sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
                                                        fieldLabel="Subtitle" name="./subheading" rows="3"/>
                                            <file jcr:primaryType="nt:unstructured"
                                                  sling:resourceType="cq/gui/components/authoring/dialog/fileupload"
                                                  fieldLabel="Background Image" name="./file" fileReferenceParameter="./fileReference"/>
                                            <ctaLabel jcr:primaryType="nt:unstructured"
                                                      sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                                      fieldLabel="CTA Label" name="./ctaLabel"/>
                                        </items>
                                    </column>
                                </items>
                            </columns>
                        </items>
                    </contentTab>
                    <!-- Style Tab -->
                    <styleTab jcr:primaryType="nt:unstructured"
                              jcr:title="Style"
                              sling:resourceType="granite/ui/components/coral/foundation/container"
                              margin="{Boolean}true">
                        <items jcr:primaryType="nt:unstructured">
                            <columns jcr:primaryType="nt:unstructured"
                                     sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
                                     margin="{Boolean}true">
                                <items jcr:primaryType="nt:unstructured">
                                    <column jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/container">
                                        <items jcr:primaryType="nt:unstructured">
                                            <overlay jcr:primaryType="nt:unstructured"
                                                     sling:resourceType="granite/ui/components/coral/foundation/form/select"
                                                     fieldLabel="Overlay" name="./overlay">
                                                <items jcr:primaryType="nt:unstructured">
                                                    <none jcr:primaryType="nt:unstructured" text="None" value="none"/>
                                                    <light jcr:primaryType="nt:unstructured" text="Light" value="light"/>
                                                    <dark jcr:primaryType="nt:unstructured" text="Dark" value="dark" selected="{Boolean}true"/>
                                                </items>
                                            </overlay>
                                            <fullWidth jcr:primaryType="nt:unstructured"
                                                       sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
                                                       text="Full Width" name="./fullWidth" value="{Boolean}true"/>
                                        </items>
                                    </column>
                                </items>
                            </columns>
                        </items>
                    </styleTab>
                </items>
            </tabs>
        </items>
    </content>
</jcr:root>
```

## 8. Dynamic Visibility (Conditional Show/Hide)

A common project requirement is to toggle visibility of fields based on another field's value. Granite UI provides built-in client library `cq-dialog-dropdown-showhide`.

Example: Display "Custom URL" field only when selecting "Custom Link" in Dropdown.

```xml
<!-- 1. Control Field (Select Dropdown) -->
<linkType jcr:primaryType="nt:unstructured"
          sling:resourceType="granite/ui/components/coral/foundation/form/select"
          fieldLabel="Link Type"
          name="./linkType">
    <granite:data jcr:primaryType="nt:unstructured"
                  cq-dialog-dropdown-showhide-target=".hero-link-options"/>
    <items jcr:primaryType="nt:unstructured">
        <none jcr:primaryType="nt:unstructured" text="None" value="none"/>
        <page jcr:primaryType="nt:unstructured" text="Internal Page" value="page"/>
        <custom jcr:primaryType="nt:unstructured" text="Custom URL" value="custom"/>
    </items>
</linkType>

<!-- 2. Dependent Field: Shown only when linkType = "page" -->
<pageContainer jcr:primaryType="nt:unstructured"
               sling:resourceType="granite/ui/components/coral/foundation/container">
    <granite:data jcr:primaryType="nt:unstructured"
                  showhidetargetvalue="page"/>
    <items jcr:primaryType="nt:unstructured">
        <linkPage jcr:primaryType="nt:unstructured"
                  sling:resourceType="cq/gui/components/coral/common/form/pagefield"
                  fieldLabel="Select Page"
                  name="./linkPage"/>
    </items>
</pageContainer>

<!-- 3. Dependent Field: Shown only when linkType = "custom" -->
<customContainer jcr:primaryType="nt:unstructured"
                 sling:resourceType="granite/ui/components/coral/foundation/container">
    <granite:data jcr:primaryType="nt:unstructured"
                  showhidetargetvalue="custom"/>
    <items jcr:primaryType="nt:unstructured">
        <linkCustom jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                    fieldLabel="Custom URL"
                    name="./linkCustom"/>
    </items>
</customContainer>
```

Add CSS class `hero-link-options` to target containers (or wrap containers in `granite:class="hero-link-options"`).

## Summary

- Touch UI Dialogs are configured via XML in `_cq_dialog/.content.xml`.
- The `./` prefix in `name` stores properties on the current component content node.
- `composite="{Boolean}true"` is required for multifields to store entries as child nodes.
- Use `cq-dialog-dropdown-showhide` for conditional field toggling.
