Skip to main content

Adobe

Dynamic Dropdowns in AEM Content Fragments

Webp.net Resizeimage (3)

In this post, I’ll show you how to easily and cleanly create a dynamic dropdown in an AEM Content Fragment Model driven by an ACS AEM Commons Generic List.

What are Content Fragments?

But first, what are Content Fragments? Content Fragments are a powerful feature in Adobe Experience Manager (AEM) for managing structure content.
Each Content Fragment has a model which defines the structure of the Content Fragment. To edit the model, Adobe provided an editor with common fields, including text fields, number fields, and dropdowns (called Enumerations).

Content Fragment Editor

Why isn’t this Out of the Box?

Unfortunately, when Adobe implemented the Content Fragment Model editor, they didn’t consider extensibility. The fields are very limited and there is no API for adding custom fields.
Despite these significant shortcomings, Content Fragments make managing simple content structures effortless, due to their simplicity and ease of use.
While Adobe made it harder for implementors by failing to follow best practices, like using Sling Resource Merger or structuring components in a sane manner, we are using Apache Sling. So, we can “kick it old school” and overlay the component.

Our Mission Statement

The Enumerations field included in Content Fragment Models only supports setting a static set of options. This is good enough for slideware, but in real life, it’s inadequate. A couple problematic use cases include:

  • Multiple models sharing the same set of values
  • Lists of options where a new options needs to be dynamically added
  • Option lists which change their options in the context of where / how the Content Fragment is used

 

The Solution

To create a dynamic dropdown, we’ll overlay the JSP script used to generate the dropdown options from the static list:

/libs/dam/cfm/admin/components/datasources/optionrenderer/optionrenderer.jsp

By creating a script at:

/apps/dam/cfm/admin/components/datasources/optionrenderer/optionrenderer.jsp

Since Sling prioritizes /apps over /libs when it looks up scripts, our script will get called instead of the original script.
The original script is simple; it hackily converts the String of comma-separated options into a com.adobe.granite.ui.components.ds.DataSource object and then sets that as a request object. Pretty easy to reproduce! But of course, we don’t want to break the existing functionality.
To avoid breaking the existing functionality, we can prefix all of our dynamic dropdowns with a known prefix. This will also allow us to even have multiple different types of dropdown population methods.
In this example, we’ll use the prefix: “acs-commons-list:” for populating a dropdown of the values of an ACS AEM Commons Generic List. Additionally, we have to use a Lambda function to map the properties in the Generic List into the format used by the DataSource. All said and done, here’s what the script looks like:

Once we have the script in place, we can use dynamic and static dropdowns together.

Dynamic Dropdowns

With this technique, we are no longer constrained to static dropdowns with AEM Content Fragments. With more prefixes, we can have even more options to populate dynamic dropdowns.

Thoughts on “Dynamic Dropdowns in AEM Content Fragments”

  1. Pretty useful article! I have a question, What if I need two custom data source for the dropdowns but I need to limit the list options of the second depending on the value selected in the first one? How to share that context data between different fields? Thanks

  2. Thanks Dan for the blog. My question is how to make this drop down multi select and store it as a string array.

  3. Suchita,
    Theoretically, you could have a similar overlay process, but overlying the main component script, not just the optionrenderer.jsp. This would be pretty custom however, so I’d first think if there’s some other way to structure your data to avoid this setup.

  4. German,
    Good question… I’d actually think you’d need to do this via a ClientLib in addition to this extension. Since the script returns the values from the server-side, you can’t have it filter based on the value of another field. You’d have to have a dropdown which has a clientlib attached which dynamically updates it’s values based on the value of the other field.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Dan Klco, Adobe Digital Marketing Technical Director

Dan is a certified Adobe Digital Marketing Technologist, Architect, and Advisor, having led multiple successful digital marketing programs on the Adobe Experience Cloud. He's passionate about solving complex problems and building innovative digital marketing solutions. Dan is a PMC Member of the Apache Sling project, frequent Adobe Beta participant and committer to ACS AEM Commons, allowing a unique insight into the cutting edge of the Adobe Experience Cloud platform.

More from this Author

Follow Us
TwitterLinkedinFacebookYoutubeInstagram