I need to pass a value from my Sling Model, for example shopId to my clientlib js associated with the AEM dialog. Following is my clientlib js for aem dialog.
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @touseefk2181136 PFA,
You may easily extract the shop id from path(string operation- split) of search result. Even we can use shopName as well shopAddress to check if present by grouping property in query.
path=/content/data/shop
property=shopName
property.value=name2
OR
path=/content/data/shop
group.1_property=shopName
group.1_property.value=name2
group.2_property=shopAddress
group.2_property.value=address2
p.limit=-1
OR if you want only if shop node has id node as a child or not and that unique id if present then we can use simple query as below
Hi @touseefk2181136 ,
You might want to check out this - https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/how-to-use-component-s-dia...
Let me know if you are still facing any issues in fetching the values to JS.
To answer it better, could you please provide details on how your sling Model is getting this shopId which you are trying to retrieve in your dialog js and what are you planning to do with this shopId once it is available in your js?
@h_kataria In my sling model, I get shop record from jcr like /content/data/shops by name. Now on the AEM dialog of my component I have fields like shop name, address etc. When user submits (click on Done or OK) AEM dialog I need to post that data to a servlet, I need to include shopId in the payload. In the servlet, I need to check if shop id exists, update the record otherwise create new shop record. Following is my client lib js code which will save shop record. But I tried using hidden field in HTL but AEM dialogue 's html doesn't that hidden field.
(function ($, $document) {
"use strict";
$(document).on("foundation-contentloaded", function (e) {
Coral.commons.ready(function () {
});
});
// When the dialog is submitted
$(document).on("click", ".cq-dialog-submit", function (e) {
let dialog = e.currentTarget.closest('coral-dialog');
let trackingFeature = dialog.getAttribute('trackingfeature');
if (trackingFeature.includes('shop form')) {
let shopName = dialog.querySelector('input[name="./shopName"]').value;
let Addres = dialog.querySelector('input[name="./Addres"]').value
var shopData = {
'shopName': shopName,
'shopId': // I need shopId here,
'Addres': shopAddress
};
$.ajax({
type: 'POST',
url: '/bin/test/shopservlet',
data: shopData,
success: function (response) {
console.log('Data saved successfully: ', response);
alert("The shop has been saved successfully")
},
error: function (error) {
console.error('Error while saving data: ', error);
alert("Error while saving data")
}
});
}
});
})(jQuery, jQuery(document));
@h_kataria Yes shopId is not part of my AEM dialog, it is autogenerated. It is GUID, when we pass data to the shop servlet to save, the shop id is generated if it is not part of the payload already. Following is the structure my node
One solution which I can think of is just make an ajax call to your /content/data/shops.infinity.json node in your js, you will get the JSON of your shops data, then you can filter out the node based on the shopName in your current component and get the shopId there itself.
Hope this helps.
Hi @touseefk2181136 ,
You may use ajax call /content/data/shops.infinity.json as suggested by @h_kataria OR you may use below approach.
From front-end just pass shopName and shopAddress only in shopData object to Servlet always.
Then in servlet itself first check if that shop name exist by fetching(making http call to /content/data/shops.infinity.json) all shop data then filter to check shop Id present OR you may use queryBuilder to search for shopId with shopName.
If shopId present you can append else generate the shopId
Thanks
Hi @touseefk2181136 PFA,
You may easily extract the shop id from path(string operation- split) of search result. Even we can use shopName as well shopAddress to check if present by grouping property in query.
path=/content/data/shop
property=shopName
property.value=name2
OR
path=/content/data/shop
group.1_property=shopName
group.1_property.value=name2
group.2_property=shopAddress
group.2_property.value=address2
p.limit=-1
OR if you want only if shop node has id node as a child or not and that unique id if present then we can use simple query as below
After going through the entire thread i guess the best option for you would be to follow the below steps as this is how i tried and worked
If you are facing any issue in this let me know
@abhishekanand_ Ok, I am doing this as per your points
1. Exposed property in sling model
@Model(adaptables = Resource.class)
public class ShopModel {
@Inject
private String shopId;
public String getShopId() {
return shopId;
}
}
2. Render value in html
<div data-shop-id="${shopModel.shopId}"></div>
3. Write JavaScript to read value.
let shopId = document.querySelector('div[data-shop-id]').getAttribute('data-shop-id');
Where I need to write this JavaScript ? If I write this in dialog.js which is my clientlib for AEM dialog then above html data attribute for shop is not available in 'document' object because its scope is coral dialog.
Kindly explain point 3 and write sample code.
4. Include the JavaScript File in Your Componen
<sly data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientLib.js @ categories='clientlib-dialog'}"></sly>
Again, after point 2, I am unable proceed document object doesn't have data attribute for shop id.
Thank you.
Hi
You can include a js at the component slightly as well, or if you want to keep your js seperate you can do that as well
<!-- /apps/myproject/components/mycomponent/mycomponent.html -->
<div class="my-component" data-myproperty="${myComponentModel.myProperty @ context='unsafe'}">
</div>
<sly data-sly-call="${'myproject.clientlib.js' @ category='myproject.mycomponent'}"></sly>
<script>
document.addEventListener('DOMContentLoaded', function() {
var myComponent = document.querySelector('.my-component');
if (myComponent) {
var myPropertyValue = myComponent.getAttribute('data-myproperty');
console.log('The value from the Sling Model is:', myPropertyValue);
// Use myPropertyValue as needed
}
});
</script>
Ok I have done above steps. I am already able to get store id in the above JavaScript code. Now I can see dialog.js clientlib js is loading when the page is loading but first problem is following event not firing. Now even if I move following code in html of the component, event doesn't fire. second problem, still don't know how to pass shop id to dialog.js client lib. If any of these two problems solved, my issue is solved.
// When the dialog is submitted
$(document).on("click", ".cq-dialog-submit", function (e) {
let dialog = e.currentTarget.closest('coral-dialog');
let trackingFeature = dialog.getAttribute('trackingfeature');
if (trackingFeature.includes('shop form')) {
let shopName = dialog.querySelector('input[name="./shopName"]').value;
let Addres = dialog.querySelector('input[name="./Addres"]').value
var shopData = {
'shopName': shopName,
'shopId': // I need shopId here,
'Addres': shopAddress
};
$.ajax({
type: 'POST',
url: '/bin/test/shopservlet',
data: shopData,
success: function (response) {
console.log('Data saved successfully: ', response);
alert("The shop has been saved successfully")
},
error: function (error) {
console.error('Error while saving data: ', error);
alert("Error while saving data")
}
});
Will be thankful if you are available for a short call so that I can show you real scenario.
Sure we can connect
Hi @abhishekanand_ just sent you meeting invite
Hi @touseefk2181136 ,
Seems as per you use case below code should work. From frontend just pass shopName and address and made changes in servlet as below.
package com.yourproject.core.servlets;//change as per you code base
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.SearchResult;
import com.google.gson.Gson;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import javax.jcr.Session;
import javax.servlet.Servlet;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Component(service = Servlet.class)
@SlingServletPaths(
value = "/bin/test/shopservlet"
)
public class ShopServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(ShopServlet.class);
@Reference
private QueryBuilder builder;
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try {
String requestBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
JsonObject shopdata = new Gson().fromJson(requestBody, JsonObject.class);
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);
Map<String, String> map = new HashMap<String, String>();
map.put("path", "/content/data/shop");
map.put("property", "shopName");
map.put("property.value", shopdata.get("shopName").getAsString());
map.put("p.limit", "-1");
Query query = builder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
int hits = result.getHits().size();
if (hits > 0) {
String shopId = result.getHits().get(0).getPath().split("/")[4];
//shopId will get appended in shopdata if shopId exist with that shopname else shopdata won't have shopId
shopdata.addProperty("shopId",shopId);
}
//write your existing servlet logic code
//here now shopData will have shopId if exist else it won't have so your existing servlet logic will work
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
However if you insist to use shopid in frontend put below new servlet to you code base and make another ajax call in your js to get shop id and append according before making call to /bin/test/shopservlet
package com.yourproject.core.servlets;//change this as per your code base
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.SearchResult;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Session;
import javax.servlet.Servlet;
import java.util.HashMap;
import java.util.Map;
@Component(service = Servlet.class)
@SlingServletPaths(
value = "/bin/test/fetchshopid"
)
public class FetchShopIdServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(FetchShopIdServlet.class);
@Reference
private QueryBuilder builder;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try {
String shopName = request.getParameter("shopname");
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);
Map<String, String> map = new HashMap<String, String>();
map.put("path", "/content/data/shop");
map.put("property", "shopName");
map.put("property.value", shopName);
map.put("p.limit", "-1");
Query query = builder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
int hits = result.getHits().size();
if (hits > 0) {
String shopId = result.getHits().get(0).getPath().split("/")[4];
response.getWriter().write(shopId);
} else {
response.getWriter().write("null");//or whatever you want to return either 0 or something
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
Ajax call endpoint :- http://localhost:6502/bin/test/fetchshopid?shopname=name2
You may pass shopName as query param to check if that shopName exist
Above Servlet will return shopid if exist else will return null string
Thanks
Hi @touseefk2181136 ,
You can just pass shopName and shopAddress to /bin/test/shopservlet and made changes in servlet as per below code.
package com.your-project-path.core.servlets;//your your code base package
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.SearchResult;
import com.google.gson.Gson;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import javax.jcr.Session;
import javax.servlet.Servlet;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Component(service = Servlet.class)
@SlingServletPaths(
value = "/bin/test/shopservlet"
)
public class ShopServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(ShopServlet.class);
@Reference
private QueryBuilder builder;
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try {
String requestBody = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
JsonObject shopdata = new Gson().fromJson(requestBody, JsonObject.class);
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);
Map<String, String> map = new HashMap<String, String>();
map.put("path", "/content/data/shop");
map.put("property", "shopName");
map.put("property.value", shopdata.get("shopName").getAsString());
map.put("p.limit", "-1");
Query query = builder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
int hits = result.getHits().size();
if (hits > 0) {
String shopId = result.getHits().get(0).getPath().split("/")[4];
shopdata.addProperty("shopId",shopId);
}
//write your existing servlet logic code here now shopData will have shopId if exist else it won't have so your existing servlet logic will work
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
OR you can use below servlet to get the shopId in js . To get shopId make a call to below servlet
package com.yourproject.core.servlets;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.SearchResult;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.servlets.annotations.SlingServletPaths;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Session;
import javax.servlet.Servlet;
import java.util.HashMap;
import java.util.Map;
@Component(service = Servlet.class)
@SlingServletPaths(
value = "/bin/test/fetchshopid"
)
public class FetchShopIdServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(FetchShopIdServlet.class);
@Reference
private QueryBuilder builder;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) {
try {
String shopName = request.getParameter("shopname");
ResourceResolver resolver = request.getResourceResolver();
Session session = resolver.adaptTo(Session.class);
Map<String, String> map = new HashMap<String, String>();
map.put("path", "/content/data/shop");
map.put("property", "shopName");
map.put("property.value", shopName);
map.put("p.limit", "-1");
Query query = builder.createQuery(PredicateGroup.create(map), session);
SearchResult result = query.getResult();
int hits = result.getHits().size();
if (hits > 0) {
String shopId = result.getHits().get(0).getPath().split("/")[4];
response.getWriter().write(shopId);
} else {
response.getWriter().write("null");//or whatever you want to return either 0 or something
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
Make an ajax call from js to get shopId with shopname as query parameter. It will return shopId or null if doesn't exist
Endpoint-
http://localhost:6502/bin/test/fetchshopid?shopname=name2
@touseefk2181136 Did you find the suggestion helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies