I have a CAC field something like below, I have a need to make the value of this field dynamically due to a strange use-case.
Is there a way I can do this in javascript or with Java code? This has to be a different value and I can't even have a pre-defined set of values for it.
@property(order = 1, label = "Dynamic Value", description = "Prefill or update this value dynamically in CA editor or while saving the config value")
String dynamicValue();
thanks.
@SantoshSai @arunpatidar , @Pranay_M , @muskaanchandwani @aanchal-sikkaEstebanBustamante
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
We were able to do this by creating a Filter for intercepting selectors
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
EngineConstants.SLING_FILTER_SELECTORS + "=" + "configPersist",
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
String configName = request.getParameter("configName");
ConfigurationMetadata configMetadata = configManager.getConfigurationMetadata(configName);
//get config fields of type=token.
Set<String> tokenFields = //using a Util class to get the field(s) to be updated. Field is identified using a type property i.e type=token.
String jsonDataString = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
JsonNode jsonNode = new ObjectMapper().readTree(jsonDataString);
JsonNode propItems = jsonNode.get("items"); // For multiple items in CA config
if (propItems != null && propItems.isArray()) {
for (JsonNode item : propItems) {
//update the properties of JsonNode, if the a property name is found from "tokenFields".
JsonNode properties = item.get("properties");
((ObjectNode) properties).put(propertyName, "a-dynaically-generated-value-here");
}
}
}
This way, before saving the CA config, we were able to update the 'dynamicValue'.
thanks
Hi @Kamal_Kishor ,
There is no out-of-the-box (OOB) solution for this requirement. Since the value is dynamically generated, I assume it does not need to be displayed in the CA Config Editor.
In that case, you can omit this property from the CA Config Editor definition and instead derive or compute the value in your Sling Model or backend logic when accessing the CA Config values.
Hi @narendiran_ravi,
I agree with @narendiran_ravi's suggestion that there is no out-of-the-box solution for dynamically setting a value in the CA editor, especially when the value needs to be generated dynamically and doesn't fit well into a predefined set.
At the moment, these are the things coming to my mind that could help solve your requirement:
If you prefer to generate the dynamic value on the server-side, you could compute the value in a Sling Model. This way, the value is not part of the configuration but can be generated dynamically when the page is loaded.
For example:
@Model(adaptables = Resource.class)
public class DynamicValueModel {
@Inject
private ValueMap properties;
public String getDynamicValue() {
// Replace this with your logic for generating the dynamic value
String dynamicValue = generateDynamicValue();
return dynamicValue;
}
private String generateDynamicValue() {
// Example logic: Generate a dynamic value (e.g., timestamp or complex logic)
return "Dynamic-" + System.currentTimeMillis();
}
}
This can then be accessed in your frontend code to display the dynamically generated value.
Alternatively, you could handle this in the backend logic by creating a service that generates the dynamic value and then saves or processes it within your configuration logic. Here’s a simple example:
@Component(service = DynamicValueService.class)
public class DynamicValueService {
public String generateDynamicValue() {
// Your logic to generate a dynamic value
return "Dynamic-" + System.currentTimeMillis();
}
}
You can reference this service in your configuration handler when saving or processing the configuration.
If you need to generate the dynamic value directly in the CA editor or on the frontend, you could use JavaScript to dynamically set the field value on page load.
Here's a simple example:
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
// Example logic to generate a dynamic value (e.g., timestamp)
var dynamicValue = "Dynamic-" + new Date().getTime();
// Set the dynamic value to the field (assuming field name is 'dynamicValue')
var field = document.querySelector("[name='dynamicValue']");
if (field) {
field.value = dynamicValue;
}
});
</script>
This method ensures that the field value is dynamically updated when the page or dialog loads.
Hope this helps!
Hi @Kamal_Kishor ,
To dynamically generate a value for a field in a Context-Aware Configuration (CAC) in AEM, especially when you can't use a predefined set of values, here's the practical way forward based on current AEM capabilities:
1. Compute Dynamically in Backend (Sling Model or Service)
Since AEM's CA Config Editor does not support truly dynamic field values in the UI (like real-time generation or async loading), the cleanest solution is:
- Omit the field from the @Property annotations
- Don't store it in the configuration at all if it's not meant to be static.
- Generate it dynamically at runtime
Use a Sling Model or OSGi service to compute the value when it's needed.
Example – Sling Model
@Model(adaptables = Resource.class)
public class MyDynamicModel {
@Inject
private ConfigurationBuilder configBuilder;
@OSGiService
private DynamicValueService dynamicValueService;
public String getDynamicValue() {
// Optional: combine with config if needed
MyConfig config = configBuilder.as(MyConfig.class);
// Return dynamically computed value
return dynamicValueService.generateValue();
}
}
And the service:
@Component(service = DynamicValueService.class)
public class DynamicValueService {
public String generateValue() {
return "Dynamic-" + System.currentTimeMillis(); // or any custom logic
}
}
If You Must Show the Field in the CA Config Editor (UI Side Hack)
If you really need a dynamic prefill in the UI, inject a value using JavaScript on dialog load (a workaround only):
JS Clientlib (included in your CA Editor page):
document.addEventListener('DOMContentLoaded', function () {
const field = document.querySelector("[name='dynamicValue']");
if (field && !field.value) {
field.value = "Dynamic-" + new Date().getTime();
}
});
This only affects what's shown or submitted it doesn’t change the underlying model logic unless persisted.
Regards,
Amit
What is the use case here? There are ways to use dynamic values.
Example -
Use placeholder and resolve placeholder
Thank you everyone for your replies.
My use-case is not very standard (users need similar behavior as we are migrating it from a different solution).
I need to generate this 'dynamicValue' first time my context aware config editor is submitted. Once it is set, it will/should not be updated.
Reason for having this field in config is that once it gets generated, authors/user want to copy this field value.
thanks.
We were able to do this by creating a Filter for intercepting selectors
EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
EngineConstants.SLING_FILTER_SELECTORS + "=" + "configPersist",
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
String configName = request.getParameter("configName");
ConfigurationMetadata configMetadata = configManager.getConfigurationMetadata(configName);
//get config fields of type=token.
Set<String> tokenFields = //using a Util class to get the field(s) to be updated. Field is identified using a type property i.e type=token.
String jsonDataString = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
JsonNode jsonNode = new ObjectMapper().readTree(jsonDataString);
JsonNode propItems = jsonNode.get("items"); // For multiple items in CA config
if (propItems != null && propItems.isArray()) {
for (JsonNode item : propItems) {
//update the properties of JsonNode, if the a property name is found from "tokenFields".
JsonNode properties = item.get("properties");
((ObjectNode) properties).put(propertyName, "a-dynaically-generated-value-here");
}
}
}
This way, before saving the CA config, we were able to update the 'dynamicValue'.
thanks
@Kamal_Kishor : Did you find the suggestions 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
Likes
Replies
Views
Likes
Replies