How to customize Participant Step dialog with dynamic checkbox values from workflow metadata? | Community
Skip to main content
Level 2
April 13, 2026
Solved

How to customize Participant Step dialog with dynamic checkbox values from workflow metadata?

  • April 13, 2026
  • 2 replies
  • 49 views

Hi all,

I'm working on an AEMaaCS workflow and would like to implement a custom Participant Step dialog with dynamic data coming from a previous Process Step.

Here is my use case:

  1. An editor starts a workflow on a Content Fragment

  2. Editor receives a notification and completes the first task

  3. A custom Process Step collects all referenced nodes under the Content Fragment and stores them into workflow metadata like below:

    item.getWorkflow().getWorkflowData().getMetaDataMap()
    .put("discoveredNodePaths", collectedPaths.toArray(new String[0]));
     

  4. In the next Participant Step:

    • Editor opens the task from Inbox
    • A dialog should display all discovered node paths as a checkbox group
    • Editor selects some nodes and clicks "Ok"
    • The selected nodes should be saved back into workflow metadata
  5. Next Reviewer step:

    • Reviewer opens task and sees selected nodes
    • Can approve or reject
  6. If approved, a Process Step publishes all selected nodes

My questions is about step4:

  1. How can I customize the Participant Step dialog in AEMaaCS?

    • Especially how to build a dynamic checkbox group based on workflow metadata?
  2. How can I read workflow metadata inside the dialog (Granite UI / Coral UI)?

  3. After user clicks "Ok", how can I persist selected values back into workflow metadata for next steps?

  4. Is this achievable with standard Participant Step dialog configuration,
    or do I need a completely custom Inbox action / UI extension?

Any guidance or example would be greatly appreciated. Thanks!

 
 

 

 

Best answer by SubbaraoGa1

@EddieHuang 

Yes, it’s achievable with a standard Dialog Participant Step, but you need:

  1. custom dialog that reads the workflow instance (and its metadata) via server-side logic (Sightly/HTL + Sling Model or JSP) and renders a dynamic checkbox list.
  2. A matching POST servlet or script that writes the selected values back into the workflow metadata when the user clicks OK in the Complete Work Item dialog.

You do not need to replace the Inbox UI; you extend the dialog that is shown inside the existing “Complete Work Item” flow.

2 replies

SubbaraoGa1Adobe EmployeeAccepted solution
Adobe Employee
April 13, 2026

@EddieHuang 

Yes, it’s achievable with a standard Dialog Participant Step, but you need:

  1. custom dialog that reads the workflow instance (and its metadata) via server-side logic (Sightly/HTL + Sling Model or JSP) and renders a dynamic checkbox list.
  2. A matching POST servlet or script that writes the selected values back into the workflow metadata when the user clicks OK in the Complete Work Item dialog.

You do not need to replace the Inbox UI; you extend the dialog that is shown inside the existing “Complete Work Item” flow.

Level 2
April 21, 2026

Thanks for the tips! I ended up got it working by using two Servlet and a Clientlibs js to handle the logic.

 
 

 

 

PGURUKRISHNA
Level 5
April 14, 2026

Hey ​@EddieHuang , The standard Participant Step dialog configuration does not support dynamic fields driven by workflow metadata out of the box. You'll need a combination of:

  1. A custom dialog resource with a dynamic Granite UI datasource

  2. A custom servlet to read workflow metadata and feed it to the dialog

  3. Standard workflow metadata persistence on dialog completion

Step-by-Step Approach:

1. Create a Custom Dialog Step 

In your workflow model, instead of using the default Participant Step dialog, define a custom Dialog Participant Step that points to a custom dialog path.

In the workflow model node (under 

/var/workflow/models/your-model

), configure the Dialog Participant Step with:

dialogPath = /apps/your-project/workflow/dialogs/select-nodes

2. Create the Custom Dialog Resource

Create a Granite UI dialog at 

/apps/your-project/workflow/dialogs/select-nodes

:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Select Nodes to Publish"
sling:resourceType="cq/gui/components/common/admin/dialog">
<content jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<nodePaths jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkboxgroup"
fieldLabel="Discovered Nodes"
name="selectedNodePaths">
<datasource jcr:primaryType="nt:unstructured"
sling:resourceType="your-project/datasources/workflow-nodes"/>
</nodePaths>
</items>
</content>
</jcr:root>

The key here is the 

datasource

 — it points to a custom Sling resource type that dynamically generates checkbox items.

3. Create the Datasource Servlet

This servlet reads 

discoveredNodePaths

 from workflow metadata and returns them as checkbox options:

package com.yourproject.core.servlets;

import com.adobe.granite.ui.components.ds.DataSource;
import com.adobe.granite.ui.components.ds.SimpleDataSource;
import com.adobe.granite.ui.components.ds.ValueMapResource;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.SlingSafeMethodServlet;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.osgi.service.component.annotations.Component;

import javax.servlet.Servlet;
import java.util.*;

import static org.apache.sling.api.servlets.ServletResolverConstants.*;

@Component(service = Servlet.class, property = {
SLING_SERVLET_RESOURCE_TYPES + "=your-project/datasources/workflow-nodes",
SLING_SERVLET_METHODS + "=GET"
})
public class WorkflowNodesDatasourceServlet extends SlingSafeMethodServlet {

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
List<com.adobe.granite.ui.components.ds.ValueMapResource> items = new ArrayList<>();

try {
// Extract workitem ID from request (AEM passes this as a parameter)
String workItemId = request.getParameter("workitem");
if (workItemId != null) {
WorkflowSession wfSession = request.getResourceResolver()
.adaptTo(WorkflowSession.class);
WorkItem workItem = wfSession.getWorkItem(workItemId);
String[] paths = (String[]) workItem.getWorkflow()
.getWorkflowData().getMetaDataMap().get("discoveredNodePaths");

if (paths != null) {
for (String path : paths) {
ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("value", path);
vm.put("text", path);
items.add(new ValueMapResource(
request.getResourceResolver(),
new ResourceMetadata(),
"nt:unstructured",
vm));
}
}
}
} catch (Exception e) {
// log error
}

request.setAttribute(DataSource.class.getName(),
new SimpleDataSource(items.iterator()));
}
}

 

4. Persisting Selected Values Back to Metadata

AEM handles this automatically for Dialog Participant Steps. When the editor clicks "Complete" in the Inbox, all form field values from the dialog are stored in the work item's metadata map.

To access the selected values in a subsequent Process Step:

@Override
public void execute(WorkItem workItem, WorkflowSession wfSession, MetaDataMap args) {
// Dialog field values are stored in the workitem metadata
String[] selectedPaths = (String[]) workItem.getWorkflow()
.getWorkflowData().getMetaDataMap().get("selectedNodePaths");

// Or from the work item's own metadata
MetaDataMap wfMeta = workItem.getMetaDataMap();
String selectedRaw = wfMeta.get("selectedNodePaths", String.class);
}

Important caveat: Dialog Participant Step stores form values in the 

WorkItem

 metadata, not the 

WorkflowData

 metadata. If you need them in 

WorkflowData

 metadata for downstream steps, add a small Process Step after the dialog step that copies values:

 

Key Considerations for AEMaaCS

  • Dialog Participant Step is the correct step type — not a plain Participant Step. It supports custom 

    dialogPath
    .
  • The 

    workitem
     request parameter availability in the datasource servlet depends on how AEM's Inbox UI renders the dialog. You may need to inspect the Inbox network calls to confirm the exact parameter name (it could be 
    item
     or 
    taskId
     in newer AEM versions).
  • If the datasource servlet cannot reliably get the work item ID from the dialog request, an alternative is to use a custom Granite UI clientlib that fetches metadata via a separate Sling servlet (AJAX call) and populates the checkboxes client-side.

  • For AEMaaCS, ensure your servlet and dialog resources are deployed via your 

    ui.apps
     module.

Folder Structure

 

The datasource 

.content.xml

 is minimal:

<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
jcr:primaryType="nt:unstructured"
sling:resourceType="your-project/datasources/workflow-nodes"/>

This approach keeps everything within standard AEM patterns — no custom Inbox UI extensions needed.

Pagidala GuruKrishna