Hi All,
We have a requirement as shown below:
1. A page (PageA) will have two components
2. First component (Component A) is a path browser which allows user to link to another page (Page B).
3.Second component (Component B) has various fields and a multifield.
4. The multifield in Component B has dropdown value field which has to be populated based on the data present in Component A
5. To accomplish this, we created a dynamic dropdown datasource on the multifield item. Datasource is mapped to a servlet.
Problem statement:
The resource path that we are getting in the servlet is the resource path of the component (Component B)
Inorder to get the path of component A, we are trying to get the current page path using
"String resourcePath = (String) request.getAttribute("granite.ui.form.contentpath");"
This will return the complete path upto the first item in the multifield. /content/site/folder/pageA/jcr:content/root/container/component/multifieldItem/item0
From here we are doing a substring to "/content/site/folder/pageA/" and appending the required path i.e /jcr:content/root/container/ComponentA
So now, "/content/site/folder/pageA/jcr:content/root/container/ComponentA" will have a property which has the link to PageB, which we are using for further processing.
While using this approach, on the first time load of the dialog, the dropdown values are not getting populated. Once one multifield item is added, dialog submitted and then reopened the values are getting populated.
We also used the below to get the page path.
Enumeration<?> values = request.getHeaders("Referer"); if (values != null) { while
(values.hasMoreElements()) { String url = (String) values.nextElement();
LOGGER.info("Resource url enumeration*****" + url); } }
As the above is not highly recommended, could any of you suggest how to retrieve the path of the page where the component is authored?
Thanks!
Solved! Go to Solution.
Hello @ReshmaRaj ,
You can try this,
In your XML,
<selectComponent
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Select Component"
multiple="{Boolean}true"
name="./selectComponent">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="aem-demo/datasource/component/json"/>
</selectComponent>
where aem-demo/datasource/component/json is your servlet path
In your servlet,
@Component(service = Servlet.class,
property = {
Constants.SERVICE_DESCRIPTION + "=AEM Demo JSON Datasource Servlet",
ServletResolverConstants.SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "=aem-demo/datasource/component/json"
})
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
ResourceResolver resourceResolver = request.getResourceResolver();
String currentPagePath = request.getRequestPathInfo().getSuffix().split("/" + JCR_CONTENT)[0];
}
Hope this will help you.
@ReshmaRaj Please check the same issue discussed before and answered.
Example from @arunpatidar : https://github.com/arunpatidar02/aem63app-repo/blob/master/js/dynamic-dropdown.js
Hi @ReshmaRaj, You can use Sling Model instead of Servlet.
<item jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/select"
fieldLabel="Select an Item"
name="./item">
<datasource jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/aem-demo/datasource/item/item.html"/>
</formElements>
apps/aem-demo/datasource/item/item.html
<sly data-sly-use.data="com.aem.demo.core.components.model.Item"></sly>
com/aem/demo/core/components/model/tem.java
@Model(
adaptables = { SlingHttpServletRequest.class },
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class Item {
@SlingObject
protected ResourceResolver resourceResolver;
@ScriptVariable
protected Page currentPage;
@PostConstruct
protected void init() {
String pageUrl = currentPage.getPath();
// Construct data resource here
}
}
Hello @ReshmaRaj ,
You can try this,
In your XML,
<selectComponent
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Select Component"
multiple="{Boolean}true"
name="./selectComponent">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="aem-demo/datasource/component/json"/>
</selectComponent>
where aem-demo/datasource/component/json is your servlet path
In your servlet,
@Component(service = Servlet.class,
property = {
Constants.SERVICE_DESCRIPTION + "=AEM Demo JSON Datasource Servlet",
ServletResolverConstants.SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "=aem-demo/datasource/component/json"
})
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
ResourceResolver resourceResolver = request.getResourceResolver();
String currentPagePath = request.getRequestPathInfo().getSuffix().split("/" + JCR_CONTENT)[0];
}
Hope this will help you.
Thanks That worked!
@ReshmaRaj We hope you found the AEM community valuable. We anticipate your return as either a learner or a contributor. The community benefits from SMEs like you. Please ask your AEM peers to join and contribute. Happy AEM learning!
Views
Replies
Total Likes