Render AEM Site Actions Dynamically using render conditions | Community
Skip to main content
Level 2
March 2, 2020
Solved

Render AEM Site Actions Dynamically using render conditions

  • March 2, 2020
  • 3 replies
  • 4929 views

I have created a custom page action button.
I need to show the Action button only when author is on a particular path in sites(http://localhost:4502/sites.html/content) view and hide otherwise. For example: i want this button only displayed when user is at any of the child pages of (http://localhost:4502/sites.html/content).
I tried using render condition for this - https://adobe-consulting-services.github.io/acs-aem-commons/features/ui-widgets/path-rendercondition/index.html
But the issue is that render condition is getting evaluated only when page is refreshed.

Is there a way i can either force re render the action bar in sites view and invoke the render condition every time user select a page in sites view ? without reloading the page

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by jithinkumar

Working Solution 🙂 

Below piece of javascript can be used to dynamically show/hide action buttons in Granite UI.

Use case - Toggle display of an action button Dynamically when user selects a Page item in either column view/ List view or card view

 

$(window).load(function () { var BUTTON1 = ".cq-siteadmin-admin-actions-button1-activator", BUTTON2 = ".cq-siteadmin-admin-actions-button2-activator", ALLOWED_PATH_PREFIX = "/content/mysites", PATH_ATTRIBUTE = "data-granite-collection-item-id", doOnSelectionChange = function (whichSelector) { $(BUTTON1).parent().hide(); $(BUTTON2).parent().hide(); var selected = $(whichSelector).filter(function (index, page) { var path = page.getAttribute(PATH_ATTRIBUTE); return path.startsWith(ALLOWED_PATH_PREFIX) && page.selected; }); if (selected.length === 1) { $(BUTTON1).parent().show(); $(BUTTON2).parent().show(); } }; $(document).on('foundation-selections-change', function (e) { switch (e.target.tagName) { case "CORAL-MASONRY": doOnSelectionChange("coral-masonry-item"); break; case "CORAL-COLUMNVIEW": doOnSelectionChange("coral-columnview-item"); break; case "TABLE": doOnSelectionChange("tr.foundation-collection-item"); break; default: return; } }); });

3 replies

arunpatidar
Community Advisor
Community Advisor
March 2, 2020

Please check similar post and solution.

there is a way by show/hide action button on click in page tree. you may need to write an servlet to call when user navigate in a tree and check user group in servlet and return true/false. And based on response shiow hide the action button.

 

https://experienceleaguecommunities.adobe.com/t5/Adobe-Experience-Manager/Asset-Collections-Action-Condition/qaq-p/322688

Arun Patidar
Level 2
March 11, 2020

Hi Arun, Thanks for the Reply and solution. Thought the approach have not solved my issue It gave some valuble directions . Based on that i could come up with a solution that worked for me.

This works for me to hide/show action buttons on click of an item in tree. works for all the three views

$(window).load(function () { var BUTTON1 = ".cq-siteadmin-admin-actions-button1-activator", BUTTON2 = ".cq-siteadmin-admin-actions-button2-activator", ALLOWED_PATH_PREFIX = "/content/mysites", PATH_ATTRIBUTE = "data-granite-collection-item-id", doOnSelectionChange = function (whichSelector) { $(BUTTON1).parent().hide(); $(BUTTON2).parent().hide(); var selected = $(whichSelector).filter(function (index, page) { var path = page.getAttribute(PATH_ATTRIBUTE); return path.startsWith(ALLOWED_PATH_PREFIX) && page.selected; }); if (selected.length === 1) { $(BUTTON1).parent().show(); $(BUTTON2).parent().show(); } }; $(document).on('foundation-selections-change', function (e) { switch (e.target.tagName) { case "CORAL-MASONRY": doOnSelectionChange("coral-masonry-item"); break; case "CORAL-COLUMNVIEW": doOnSelectionChange("coral-columnview-item"); break; case "TABLE": doOnSelectionChange("tr.foundation-collection-item"); break; default: return; } }); });

 

BrianKasingli
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
March 2, 2020

@jithinkumar,

In the way of serverside render, you can:

1. Create a component with a one to one relationship with a Sling Model.

2. The Sling Model will expose a property of "isChildPage", and is evaluated within the logic of the Sling Model.

 

@Model(adaptables=Resource.class) public class MyModel { @Getter private boolean isChildPage = false; @PostConstruct protected void initComponent() { // pseudo-code // if currentPage.path equals to CONST.CHILD_PAGE_PATTERN // isChildPage = true; } }

 

3. Simply add logic into your HTL Sightly as (wcmmode.edit means that you are in author):

 

<div data-sly-test="${wcmmode.edit}" data-sly-use.mymodel="sling.models.MyModel"> <a data-sly-test="${!mymodel.isChildPage}" href="/parent.html"> Parent Page </a> <a data-sly-test="${mymodel.isChildPage}" href="/child-page.html"> Child Page </a> </div>

 

4. Don't forget to apply Sling Model Unit Tests: https://sourcedcode.com/aem-sling-models-unit-test-junit-4-with-examples
I hope this helps.

Level 2
March 11, 2020
Thank you for the Reply. But my use case is different I want to show/hide page actions in granite UI and not components that are with in a page 🙂 I have posted the working solution in my reply to @arunpatidar comment
jithinkumarAuthorAccepted solution
Level 2
March 11, 2020

Working Solution 🙂 

Below piece of javascript can be used to dynamically show/hide action buttons in Granite UI.

Use case - Toggle display of an action button Dynamically when user selects a Page item in either column view/ List view or card view

 

$(window).load(function () { var BUTTON1 = ".cq-siteadmin-admin-actions-button1-activator", BUTTON2 = ".cq-siteadmin-admin-actions-button2-activator", ALLOWED_PATH_PREFIX = "/content/mysites", PATH_ATTRIBUTE = "data-granite-collection-item-id", doOnSelectionChange = function (whichSelector) { $(BUTTON1).parent().hide(); $(BUTTON2).parent().hide(); var selected = $(whichSelector).filter(function (index, page) { var path = page.getAttribute(PATH_ATTRIBUTE); return path.startsWith(ALLOWED_PATH_PREFIX) && page.selected; }); if (selected.length === 1) { $(BUTTON1).parent().show(); $(BUTTON2).parent().show(); } }; $(document).on('foundation-selections-change', function (e) { switch (e.target.tagName) { case "CORAL-MASONRY": doOnSelectionChange("coral-masonry-item"); break; case "CORAL-COLUMNVIEW": doOnSelectionChange("coral-columnview-item"); break; case "TABLE": doOnSelectionChange("tr.foundation-collection-item"); break; default: return; } }); });
BrianKasingli
Community Advisor and Adobe Champion
Community Advisor and Adobe Champion
March 11, 2020

Nice one. I would add a small improvement in your solution. Add a conditional statement before any of the Javascript is ran at all. Something like, 

$(document).on('foundation-selections-change', function (e) { if (window.location.href.indexOf('/content/mysite') == -1) return; switch (e.target.tagName) { case "CORAL-MASONRY": doOnSelectionChange("coral-masonry-item"); break; case "CORAL-COLUMNVIEW": doOnSelectionChange("coral-columnview-item"); break; case "TABLE": doOnSelectionChange("tr.foundation-collection-item"); break; default: return; } });

Remember, in the future, your AEM instance can hold more than one site.