Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
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.