Expand my Community achievements bar.

SOLVED

Dynamic Dropdown is working but Json arrays are displaying above dropdown field in dialogbox

Avatar

Employee

Hi Everyone,

              I have a requirement - In test dropdown component I have two fields ingredient name(select field), quanitity. Ingredient name field dropdown values should be fetch from content fragment.

           In the content fragment I have configured ingredient name as multifield, values are fetching properly from cf and also displaying. But the problem is above the dropdown field I am getting servlet response(json array values). Can anyone help me to resolve my query asap.

          Thanks in advance. Here below I will post my implementaiton code.
 @Shiv_Prakash_Patel  @Mani_kumar_  @Veena_Vikraman  @aanchal_sikka 

@arunpatidar 

 

Servlet code:

package com.itc.foods.brands.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.day.cq.commons.jcr.JcrConstants;
import org.apache.commons.collections4.iterators.TransformIterator;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Servlet;
import java.io.IOException;
import java.util.HashMap;

@Component
(
service = Servlet.class,
property = {
"sling.servlet.paths=/bin/recipeIngredients",
"sling.servlet.methods=GET",
"sling.servlet.extensions=json"
}
)
public class RecipeIngredientsServlet extends SlingSafeMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(RecipeIngredientsServlet.class);


private String contentFragmentPath;


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

ResourceResolver resourceResolver = request.getResourceResolver();

contentFragmentPath = "/content/dam/project1/content-fragments/recipe-ingredients-list/jcr:content/data/master";

log.info("Retrieved content fragment resource at path: {}", contentFragmentPath);

//JsonArray ingredientsList = new JsonArray();

JsonArray dropDownList = new JsonArray();

// Retrieve content fragment resource
Resource contentFragmentResource = request.getResourceResolver().getResource(contentFragmentPath);

if (contentFragmentResource != null) {
try {
ValueMap contentFragmentProperties = contentFragmentResource.adaptTo(ValueMap.class);

String[] ingredientNames = contentFragmentProperties.get("ingredients", String[].class);

for (int i = 0; i < ingredientNames.length; i++) {
JsonObject ingredientObject = new Gson().fromJson(ingredientNames[i], JsonObject.class);
//ingredientsList.add(ingredientObject);

// Extract key and value for dropDownList
String ingredientName = ingredientObject.get("ingredientName").getAsString();
JsonObject dropDownItem = new JsonObject();
dropDownItem.addProperty("key", ingredientName);
dropDownItem.addProperty("value", ingredientName);
dropDownList.add(dropDownItem);
}

JsonObject finalResponse = new JsonObject();
//finalResponse.add("ingredientsList", ingredientsList);
finalResponse.add("dropDownList", dropDownList);

log.info("Final Response: {}", finalResponse);
response.getWriter().write(finalResponse.toString());

@SuppressWarnings("unchecked")
DataSource ds = new SimpleDataSource(
new TransformIterator<>(
dropDownList.iterator(),
input -> {
JsonObject obj = (JsonObject) input;
String value = obj.get("key").getAsString();
String text = obj.get("value").getAsString();

ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("value", value);
vm.put("text", text);

return new ValueMapResource(
resourceResolver, new ResourceMetadata(),
JcrConstants.NT_UNSTRUCTURED, vm);
}));
request.setAttribute(DataSource.class.getName(), ds);
} catch (Exception e) {
log.error("An error occurred: ", e);
}
}
}
}



Dialog xml:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Test dropdown"
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">
<items jcr:primaryType="nt:unstructured">
<properties
jcr:primaryType="nt:unstructured"
jcr:title="Properties"
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"
sling:resourceType="granite/ui/components/coral/foundation/container">
<ingredientName
cq:showOnCreate="{Boolean}true"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Ingredient Name"
name="./ingredientName"
required="{Boolean}true">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="/bin/recipeIngredients"/>
</ingredientName>
<ingredientQuantity
cq:showOnCreate="{Boolean}true"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Configure the ingredient quantity along with quantity unit. Eg: 2 Tbsp"
fieldLabel="Ingredient Quantity"
name="./ingredientQuantity"/>
</items>
</column>
</items>
</columns>
</items>
</properties>
</items>
</tabs>
</items>
</content>
</jcr:root>
1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @jeromeleslyv 

 

I saw a similar implementation in the below URL where they are setting the dynamic dropdown from different sources. 

https://unlocklearning.in/dynamic-dropdown-in-aem/ Please refer the servlet implementation 

 

One difference I can see with your code is you are writing the json array response here and then creating the datasource to populate the dropdown control . I believe Data source population should suffce your usecase for getting those values there

 response.getWriter().write(finalResponse.toString());

 

View solution in original post

3 Replies

Avatar

Correct answer by
Community Advisor

Hi @jeromeleslyv 

 

I saw a similar implementation in the below URL where they are setting the dynamic dropdown from different sources. 

https://unlocklearning.in/dynamic-dropdown-in-aem/ Please refer the servlet implementation 

 

One difference I can see with your code is you are writing the json array response here and then creating the datasource to populate the dropdown control . I believe Data source population should suffce your usecase for getting those values there

 response.getWriter().write(finalResponse.toString());

 

Avatar

Employee

Thank you so much for your response @sherinregi . It's a simple thing but helped me a lot.