AEM Customization: How to Add a Custom Action Button to the AEM Assets Action Bar Menu


Recently, a client approached us with a requirement to update content fragment elements data, Assets metadata, and Folder metadata via an Azure-based API. Our initial solution was to implement a JMX script, which could be started by an admin user group with valid parameters. However, this was a rather limiting solution, as normal AEM authors did not have the necessary permissions to perform these operations.

To solve this problem, the client requested us to provide a custom action button in the AEM Assets Menu. This button would enable AEM authors who have permission to modify the AEM Asset metadata to update the AEM assets by triggering the action button for the selected AEM assets. This custom implementation proved to be very helpful to the client, as they could easily access the AEM Assets Menu and trigger the custom action button.

Preview Custom Action Button

AEM Asset – Preview Custom Action Button

This blog post will discuss how we implemented this custom action button.

Overlay the Node

  1. Go to AEM’s CRXDE.
  2. Jump on /libs/dam/gui/content/assets/jcr:content/actions/selection Path
  3. Right-click on the Selection node and select the Overlay Node option from the pop-up menu.
    Overlay Node Pop Up Menu Custom Action Button

    AEM – Overlay Node Pop-Up Menu

    Overlay Node Pop Up Setting Custom Action Button

    AEM – Overlay Node setup

  4. Make sure the Overlay location is under /apps/ folder, and the Match Node Types option should be checked.
  5. This will look as follows.
    Overlayed Node Custom Action Button

    AEM- Overlay Path location in CRDEX

Add Custom Action Bar Node

To add a custom action button in the Action menu, we need to create one action bar child node below Selection Now. Let’s do that!

  1. Create a node named custom-action-btn (you can put any name here) and set the following properties on a node.
    Custom Action Btn Node Custom Action Button

    AEM CRXDE – Custom Action Button Node

    XML Format

    <custom-action-btn
        granite:class="foundation-collection-action suraj-custom-action-btn"
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/collection/action"
        activeSelectionCount="single"
        icon="refresh"
        text="Refresh Asset Data"
        title="Refresh Asset Data"
        variant="actionBar">
        <granite:rendercondition
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/renderconditions/and">
            <haspermission
                jcr:primaryType="nt:unstructured"
                sling:resourceType="dam/gui/coral/components/commons/renderconditions/haspermissions"
                path="${requestPathInfo.suffix}"
                privileges="[modify_property]"/>
        </granite:rendercondition>
    </custom-action-btn>
    
  2. You can also set granite:rendercondition if you want to handle specific scenarios in order to display this custom action button (example Provided in the above code to display this action button to the AEM user who has modify_property permission)

we are done with the overlay part. The next step is to write a custom action using Ajax call, or else you can also use custom wizards to perform any operation using this action button. But here, I will be handling custom actions using Ajax calls.

To show the action button for specific conditions, let’s consider action button should only display when the AEM author selects the Content Fragment; in that case, we need to write a custom JS code to enable and disable the visibility for the action button.

Create a JS file inside the client library folder by specifying clientlib categories as dam.gui.actions.coral

  • Asset-editor-action-btn-visibility.js
    (function(document, $) {
        "use strict";
    
        //initially hide the refressh asset button
        $(document).trigger("foundation-contentloaded");
        $(".suraj-custom-action-btn").addClass("foundation-collection-action-hidden");
    
        // hide/show refressh asset btn when author select CF asset.
        $(document).on("foundation-selections-change", ".foundation-collection", function(e) {
            let view = $("body").data("shell-collectionpage-view-layoutid");
            if (view === "list" || view === "column") {
                let selectedItem = $(this).find(".foundation-collection-item.foundation-selections-item");
                let itemType = $(selectedItem).data("editorkey");
                if (itemType?.trim() === "contentfragment") {
                    var contentFragmentPath = $(selectedItem).data("foundation-collection-item-id");
                    if(contentFragmentPath.includes("/sample-cf/")){
                        $(".suraj-custom-action-btn").removeClass("foundation-collection-action-hidden");
                    }
                }
            } else if (view === "card") {
                let selectedItem = $(this).find(".foundation-collection-item.foundation-selections-item");
                let itemType = $(selectedItem).find("[data-editorkey]").data("editorkey");
                if (itemType?.trim() === "contentfragment") {
                    var contentFragmentPath = $(selectedItem).data("foundation-collection-item-id");
                    if(contentFragmentPath.includes("/projects/")){
                        $(".suraj-custom-action-btn").removeClass("foundation-collection-action-hidden");
                    }
                }
            }
        });
    })(document, Granite.$);
    

    Now create another JS file to handle the custom action when the Author triggers the custom action button.

  • Trigger-custom-action-btn.js
    (function(document, $) {
        "use strict";
    
        // On click of Refresh Asset button update the selected CF
        $(document).on("click", ".foundation-collection-action.suraj-custom-action-btn", function(e) {
            let selectedElements = $(".foundation-collection-item.foundation-selections-item.is-selected");
            var items = [];
            $(selectedElements).each(function(e) {
                let data = $(this).data("foundation-collection-item-id");
                items.push(data);
            });
            let message = "<h3>Updating data for following Selected CF</h3>" + items.toString().replaceAll(",", "<br>");
            //Show wait ticker untill response is received from ajax call.
            const $UI = $(window).adaptTo("foundation-ui");
            var $waitTicker = $UI.waitTicker("Updating Asset", message);
    
            // Ajax to update selected CF.
            $.ajax({
                type: 'POST',
                url: '<Enter servlet path or API Path which will return the JSON output>',
                data: JSON.stringify(items),
                contentType: "application/json",
                dataType: "json",
                success: function(response) {
                    if (response.status === 200) {
                 // do some additional stuff with response as per requirement.
                        $UI.alert("Success", response.message, "success");
                        $waitTicker.clear();
                    } else {
                        $UI.alert("Error", "Failed to update selected Content Fragments", "error");
                        $waitTicker.clear();
                    }
                },
                error: function() {
                    $UI.alert("Error", "Failed to update selected Content Fragments", "error");
                    $waitTicker.clear();
                }
            });
        });
    })(document, Granite.$);
    

    Include both the JS files in the js.txt file of your client library folder.

We are done with the implementation part. Now go to the Asset folder and select any Content Fragment. The action button named Refresh Asset Data item appears in the top action bar asset Menu Navigation. Click the Refresh Asset data button to see the following pop-up window for trigger action!

Final Output Custom Action Button

AEM – Final Output of Custom Action Button

Checkout my Adobe AEM-related perficient blogs here…





Source link

Social media & sharing icons powered by UltimatelySocial
error

Enjoy Our Website? Please share :) Thank you!