AEM – Nested Multifield Dialog

Nested multifield dialogs in AEM refer to a situation where a multifield dialog is nested within another multifield dialog. This can be useful when you have a complex set of data that needs to be input by the user.

To achieve this, we will create a nested multifield dialog with two levels.

Here are the steps:

  1. Create a new component in AEM called “item-list”.
  2. Create a dialog for the component by right-clicking on the component folder and selecting “Create Dialog”. Name the dialog “dialog”.
  3. In the dialog editor, create a multifield by clicking on the “+” button in the sidekick and selecting “Multifield”. Name the multifield “items” and set the label to “Items”.
  4. Click on the multifield to open its properties. In the properties pane, set the “Min Items” to 1 and the “Max Items” to -1 (to allow an unlimited number of items).
  5. Click on the “+” button in the multifield to create a child dialog for each item. Name the child dialog “item” and set the label to “Item”.
  6. In the child dialog editor, add the following fields:
    • Textfield: “Title”
    • Textarea: “Description”
    • Multifield: “Links”
  7. Click on the “Links” multifield to open its properties. Set the “Min Items” to 0 and the “Max Items” to -1.
  8. Click on the “+” button in the “Links” multifield to create a child dialog for each link. Name the child dialog “link” and set the label to “Link”.
  9. In the link dialog editor, add a textfield for the URL and a checkbox for “Open in new window”.
  10. Save the link dialog and the item dialog.
  11. Back in the item dialog, click on the “Links” multifield again and select “Edit” for the “link” dialog.
  12. Set the “Name” to “links” and the “Field Label” to “Links”.
  13. Save the item dialog and the main dialog.

Now, when an author opens the “item-list” component for editing, they will see a “Items” multifield. Each item in the multifield will have a “Title” textfield, a “Description” textarea, and a “Links” multifield. Each link in the “Links” multifield will have a “URL” textfield and an “Open in new window” checkbox.

The author can add and remove items and links as needed, and the data will be saved in a nested structure in the content repository. You can access this data in your component’s backend code using the “ValueMap” API.

Now, we need to create a Sling Model to handle the data from the dialog.

Here are the steps:

  1. Create a new Java class in your AEM project called “ItemList.java”.
  2. Annotate the class with the “@Model” annotation to make it a Sling Model. You can also specify a resource type for the model to make it associated with the “item-list” component.

    For example:

    @Model(adaptables = Resource.class, resourceType = "my-project/components/item-list")
    public class ItemList {
        ...
    }
  3. Add fields to the class to represent the data from the dialog. We’ll create a nested structure using Lists and Maps to match the structure of the dialog.

    For example:

    private List<Map<String, Object>> items = new ArrayList<>();
  4. Create getter and setter methods for the fields.
  5. In the constructor, retrieve the data from the Sling Resource using the “ValueMap” API. You’ll need to traverse the nested structure of the data to populate your Java fields.

    Here’s an example:

    public ItemList(Resource resource) {
        ValueMap properties = resource.getValueMap();
        if (properties.containsKey("items")) {
            List<Map<String, Object>> items = new ArrayList<>();
            for (ValueMap item : properties.get("items", new ValueMap[0])) {
                Map<String, Object> itemMap = new HashMap<>();
                itemMap.put("title", item.get("title", ""));
                itemMap.put("description", item.get("description", ""));
                if (item.containsKey("links")) {
                    List<Map<String, Object>> links = new ArrayList<>();
                    for (ValueMap link : item.get("links", new ValueMap[0])) {
                        Map<String, Object> linkMap = new HashMap<>();
                        linkMap.put("url", link.get("url", ""));
                        linkMap.put("newWindow", link.get("newWindow", false));
                        links.add(linkMap);
                    }
                    itemMap.put("links", links);
                }
                items.add(itemMap);
            }
            this.items = items;
        }
    }
  6. Add a method to the class that returns the items field.
  7. In your JSP or HTML template for the component, use the “WCMUsePojo” API to bind the Sling Model to the template.

    For example:

    <sly data-sly-use.itemList="my.project.models.ItemList" />
  8. Use the itemList.getItems() method to access the data from the Sling Model in your template. You can use loops and conditionals to render the data as needed.
  9. When the author submits the dialog, AEM will automatically save the data to the content repository. To handle this data on the backend, you can use the “PostConstruct” annotation on a method in your Sling Model to process the data after it’s been saved.

    For example:

    @PostConstruct
    public void processFormData() {
        // do something with the data from the dialog
    }

I hope this explanation helps you understand how to use a Sling Model to handle data from a nested multifield dialog in AEM.

Wordpress Social Share Plugin powered by Ultimatelysocial
Wordpress Social Share Plugin powered by Ultimatelysocial