You frequently require a special ID for the AEM component. Either a backend server-side call or a custom JS action trigger are required. If the component is dragged and placed on the page more than once, the hard-coded field ID is not guaranteed to be unique.
When considering ID, you might consider directly using the global HTL objects and getters, such as ${currentNode.name}. If the component is used in other containers on the same page, this will not, however, fix the issue. Despite the fact that the JCR node level API produces a distinct id for the current node, the id also includes the node path and forward slashes, exposing the internal content structure and making it challenging to utilize in CSS and JS without escaping.
The id element is made simple to use by CSS and JS by the hash code, which also encapsulates and hides internal path information from the end-user. The developer passes in the ID prefix to make the ID property easier for humans to read. Example code of a Java Sling Model class is provided below.
Sightly
1 2 3 4 5 6 | <sly data-sly-use.componentId="com.sourcedcode.core.models.utils.ComponentId"></sly> <div id="${componentId.id}" class="cmp-header"> </div> // this produces <div id="cmpheader3901793341" class="cmp-header"></div> |
Java Sling Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.sourcedcode.core.models.utils; import com.day.cq.wcm.api.components.Component; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.ScriptVariable; import org.apache.sling.models.annotations.injectorspecific.SlingObject; @Model(adaptables = {SlingHttpServletRequest.class, Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class ComponentId { @ScriptVariable private Component component; @SlingObject private Resource resource; public String getId() { return component.getName() + "-" + String.valueOf(Math.abs(resource.getPath().hashCode() - 1)); } } |
Last Thoughts
You can improve this setup by adding an “advanced” tab in the component’s Touch UI dialog to have authors insert their own custom component ID. If the author’s configuration is empty, this mechanism will be kicked in to use the ComponentId Sling Model to generate the Ids.
1 2 3 4 5 6 | <sly data-sly-use.componentId="com.sourcedcode.core.models.utils.ComponentId"></sly> <div id="${properties.customComponentId || componentId.id}" class="cmp-header"> </div> // this produces <div id="cmpheader3901793341" class="cmp-header"></div> |