Force Selection for Tags Field

Exposing hidden features of the CFM editor in AEM - Part 2

Back to Insights
/de/en/insights
Share

With the tag field inside the AEM Content Fragment Models (CFMs) you can add tags as content to Content Fragments (CFs). This is a very helpful component to reuse the powerful AEM tags functionality also inside content.

But the field has one big disadvantage: the author can input their own tags that will be stored at a default namespace and not in your probably well thought out tags structure.

How to add a force selection functionality

So now we need to think about a solution on how to force the user to select only the already created tags to prevent chaos in our tags. And here a little bit of AEM reverse engineering can help big time.

Let's have a look at the component AEM is using for this tag field. You can find the CFM components under this path:

  • /libs/settings/dam/cfm/models/formbuilderconfig/datatypes/items
Tag field properties in CRX
medium

And here we see now that the tag field is of resourceType

  • /libs/cq/gui/components/coral/common/form/tagfield

Now we can look inside the implementation and look at the  render.jsp of this field:

render jsp of tag field
medium

Isn't that exactly what we are searching for? 🥳

Great - but how can we use it now in our Content Fragment Model? For this we need to do some more  reverse engineering.

Let's have a look again at the CFM tag field and see how it's built together. For that we can have a look at the  fieldProperties  at

  • /libs/settings/dam/cfm/models/formbuilderconfig/datatypes/items/tagfield/tagsfields.jsp (see the picture above)
tagsfield hidden properties
medium

In the  tagsfields.jsp  we can see that "forceSelection" property is already set to false permanently. So we need to  overlay  this file in order to expose the property to the CFM author.

To do that you can create a file "tagsfields.jsp" at the  exact same path but under /apps

  • /apps/settings/dam/cfm/models/formbuilderconfig/datatypes/items/tagfield/tagsfields.jsp

And inside this file we will copy the content from the /libs file and modify it accordingly:

custom tagsfields.jsp
medium

For copy pasting:

<%@ page import="org.apache.sling.api.resource.ValueMap" %><%
%><%@include file="/libs/granite/ui/global.jsp" %><%
%><%@ page session="false" contentType="text/html" pageEncoding="utf-8"
import="com.adobe.granite.ui.components.formbuilder.FormResourceManager,
org.apache.sling.api.resource.Resource,
org.apache.sling.api.resource.ValueMap,
java.util.HashMap"%><%

ValueMap fieldProperties = resource.adaptTo(ValueMap.class);
String key = resource.getName();
String xssKey = xssAPI.encodeForHTMLAttr(key);
%>

<input type="hidden" name="./content/items/<%= xssKey %>/multiple" value="false">
<input type="hidden" name="./content/items/<%= xssKey %>/cq:showOnCreate" value="true">
<input type="hidden" name="./content/items/<%= xssKey %>/autocreateTag" value="true">
<!-- BEGIN ORIGINAL FIELD -->
<!--<input type="hidden" name="./content/items/<%= xssKey %>/forceSelection" value="false">-->
<!-- END ORIGINAL FIELD -->

<!-- BEGIN CUSTOM CODE -->
<%
HashMap<String, Object> values = new HashMap<String, Object>();
values.put("granite:class", "checkbox-label forceSelection");
values.put("text", i18n.get("Force Selection"));
values.put("value", true);
values.put("uncheckedValue", false);
values.put("checked", Boolean.valueOf(fieldProperties.get("forceSelection", String.class)));
values.put("name", "./content/items/" + xssKey + "/forceSelection");

FormResourceManager formResourceManager = sling.getService(FormResourceManager.class);
Resource placeholderFieldResource = formResourceManager.getDefaultPropertyFieldResource(resource, values);

%><sling:include resource="<%= placeholderFieldResource %>" resourceType="granite/ui/components/coral/foundation/form/checkbox"/>
<!-- END CUSTOM CODE -->

With that custom code we now have the  forceSelection property as checkbox inside the CFM editor and the user can only select the tags but not create new ones.

Force Selection inside Content Fragment Model Editor
medium

Disclaimer

By  extending AEM out-of-the-box functionality  we always need to question ourselves  if it's worth the risk  to overlay. Because a  new AEM release  can contain changes at our changed files and could lead to  unforeseen problems  as there is no way to know what changed if you are not looking into the jsp/html/.. files in folder  /libs  directly.

In this case the risk is fairly low  because we are changing only a single small jsp file. But also for this jsp we need to see what changes have been made with every AEM upgrade we do.

Tested with AEM 6.5.17

More on extending the Content Fragment functionality can be found here:

Part 1

Part 3

Let’s create something great.
We bring bold ideas to life. As your partner for digital transformation, we’re here to support shaping outstanding projects for leading brands. Reach out and discover how our expertise can drive your success.
/content/dam/ews/videos/alex_hands_contact_code_2K_recbitrate.mp4
Let’s talk
/de/en/about-eggs/contact
Your next big project starts here.
Looking for fresh ideas, innovative solutions, or a partner who takes your goals seriously? Let’s connect and start building success together.