Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Render AEM Site Actions Dynamically using render conditions

Avatar

Level 2

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...
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

1 Accepted Solution

Avatar

Correct answer by
Level 2

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;
        }
    });
});

View solution in original post

6 Replies

Avatar

Community Advisor

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-C...



Arun Patidar

Avatar

Level 2

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;
        }
    });
});

 

Avatar

Community Advisor

@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.

Avatar

Level 2
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

Avatar

Correct answer by
Level 2

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;
        }
    });
});

Avatar

Community Advisor

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.