Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

Load dropdown dynamically on AEM Dialog

Avatar

Level 2

I am using citytechinc cq complonent plugin to create components in AEM using Java classes. When I use following dropdown with hardcoded option, it works fine.

@ValueMapValue
private String stores;

@DialogField(fieldLabel = "Stores", ranking = 10) @Selection(type = Selection.SELECT, options = {
@Option(text = "Store1", value = "556"),
@Option(text = "Store2 n Barrels", value = "475"),
@Option(text = "Store3 Hive", value = "2547"),
})
public String getStores() {
return stores;
}

But I use following dropdown to load it dynamically using a servlet. The dropdown remains empty on the AEM dialog. 

 

@ValueMapValue
private String stores;

@DialogField(fieldLabel = "Stores", ranking = 10)
@Selection(type = Selection.SELECT, dataSource = "/bin/store/storeoptions.json")
public String getStores() {
return stores;
}

Following is my servlet 


@Component(service = Servlet.class,
property = {
"sling.servlet.methods=" + HttpConstants.METHOD_GET,
"sling.servlet.paths=" + "/bin/store/storeoptions"
})
public class StoreOptionsServlet extends SlingAllMethodsServlet {


@Override
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws IOException {
resp.setContentType("application/json");

List<OptionItem> options = new ArrayList<>();
options.add(new OptionItem("25365", "Store1"));
options.add(new OptionItem("16726", "Store2"));
options.add(new OptionItem("31280", "Store3"));
// Add more options as needed

resp.getWriter().write(new Gson().toJson(options));
}
}

Any help is appriciated.

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Level 4

I have also not worked on this plugin, but I think the datsource implementation is generally done in a different way. Something like  

 protected void doGet(final SlingHttpServletRequest req,
                         final SlingHttpServletResponse resp) throws IOException {
        
ResourceResolver resourceResolver = request.getResourceResolver();
List<Resource> options = new ArrayList<>();
ValueMap option = new ValueMapDecorator(new HashMap<>());
option.put("text", "25365");
option.put("value", "Store1");
                            //Add more
options.add(new ValueMapResource(resourceResolver, new ResourceMetadata(), NT_UNSTRUCTURED, option));
DataSource dataSource = new SimpleDataSource(options.iterator());
request.setAttribute(DataSource.class.getName(), dataSource);

}

 

 

View solution in original post

5 Replies

Avatar

Community Advisor

Hi, 

Unfortunately, this is a custom framework that I personally have not worked on. So if you don't have any logs or something I think is hard to see what's going on. However, I think the best place to post this is in the official git repository. You can create an issue here: https://github.com/icfnext/cq-component-maven-plugin/issues 

 

Hope this helps



Esteban Bustamante

Avatar

Level 9

Hi @touseefk2181136 ,

To load a dropdown dynamically in an AEM dialog using a servlet, you need to ensure that the servlet correctly returns the options in a format that AEM expects. Your current servlet is returning a JSON array, but AEM's Coral UI dropdown component expects a specific structure.

Step-by-Step Guide

  1. Modify the Servlet to Return the Correct JSON Format The JSON format expected by AEM Coral UI dropdown is an array of objects with value and text properties. Additionally, the servlet path should match the dataSource path in your dialog field annotation.

    Update your servlet to match this format:

 

@Component(service = Servlet.class,
        property = {
                "sling.servlet.methods=" + HttpConstants.METHOD_GET,
                "sling.servlet.paths=" + "/bin/store/storeoptions.json"
        })
public class StoreOptionsServlet extends SlingAllMethodsServlet {

    @Override
    protected void doGet(final SlingHttpServletRequest req,
                         final SlingHttpServletResponse resp) throws IOException {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");

        List<Map<String, String>> options = new ArrayList<>();
        options.add(createOption("556", "Store1"));
        options.add(createOption("475", "Store2 n Barrels"));
        options.add(createOption("2547", "Store3 Hive"));
        // Add more options as needed

        resp.getWriter().write(new Gson().toJson(options));
    }

    private Map<String, String> createOption(String value, String text) {
        Map<String, String> option = new HashMap<>();
        option.put("value", value);
        option.put("text", text);
        return option;
    }
}

 

Ensure the Data Source Path is Correct Make sure that the dataSource path in your @DialogField annotation matches the servlet path:

 

@ValueMapValue
private String stores;

@DialogField(fieldLabel = "Stores", ranking = 10)
@Selection(type = Selection.SELECT, dataSource = "/bin/store/storeoptions.json")
public String getStores() {
    return stores;
}

 

Ensure the JSON Format The JSON returned by the servlet should look like this:

 

[
    { "value": "556", "text": "Store1" },
    { "value": "475", "text": "Store2 n Barrels" },
    { "value": "2547", "text": "Store3 Hive" }
]

 

  1. Build and Deploy Ensure you build and deploy your changes correctly. After deploying, the servlet should be accessible at the specified path (/bin/store/storeoptions.json).

  2. Verify the Servlet Output Before checking the dialog, ensure that your servlet returns the correct JSON output by accessing the URL directly in your browser or using a tool like Postman:

 

http://<your-aem-host>:<port>/bin/store/storeoptions.json

 

  1. Check Dialog Configuration Ensure that your dialog is correctly configured to use the data source. You can inspect the dialog in AEM to verify that the data source URL is correct and the JSON output matches the expected format.

Common Issues and Solutions

  • Empty Dropdown: If the dropdown remains empty, ensure that the servlet returns the correct JSON format and that the URL is accessible.
  • Cache Issues: Sometimes, AEM caches the dialog. Clear the cache or restart AEM to ensure the latest changes are picked up.
  • Permission Issues: Ensure that the servlet is accessible without authentication if it's supposed to be public. You might need to adjust the OSGi configurations or permissions.

By following these steps, you should be able to load the dropdown dynamically in your AEM dialog.

Avatar

Administrator

@touseefk2181136 Did you find the suggestions from users helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni

Avatar

Correct answer by
Level 4

I have also not worked on this plugin, but I think the datsource implementation is generally done in a different way. Something like  

 protected void doGet(final SlingHttpServletRequest req,
                         final SlingHttpServletResponse resp) throws IOException {
        
ResourceResolver resourceResolver = request.getResourceResolver();
List<Resource> options = new ArrayList<>();
ValueMap option = new ValueMapDecorator(new HashMap<>());
option.put("text", "25365");
option.put("value", "Store1");
                            //Add more
options.add(new ValueMapResource(resourceResolver, new ResourceMetadata(), NT_UNSTRUCTURED, option));
DataSource dataSource = new SimpleDataSource(options.iterator());
request.setAttribute(DataSource.class.getName(), dataSource);

}

 

 

Avatar

Level 2

@h_kataria Thank you very much. This is exactly what I was looking for, now I am able to load dropdown dynamically.