Important Notice

This blog has been moved! Visit the new location at https://medium.com/@arunpatidar26/list/aem-dbc5a3e4df7c.
Showing posts with label granite. Show all posts
Showing posts with label granite. Show all posts

AEMaaCS - Authoring - Component Readme as help document

AEM Components - Markdown Documentation

The Granite UI widget fieldDescription property is used to add helpful tooltips to your dialog fields but in some cases, you might need to add details documentation about the component, whether it’s technical or for Authoring instructions. 

Then you may use dialogs helpPath property to link component document to the dialog, the path could be github page or confluence page or any other page. For instance core components uses adobe documents as help document for the component, example Core Image component

jcr:title="Image"
sling:resourceType="cq/gui/components/authoring/dialog"
helpPath="https://www.adobe.com/go/aem_cmp_image_v3"


Wondering if the this documentation can be part of AEM or dialog itself.

Ahmed Musallam has created a blog about reading readme file and generating document when click on help link. You should check this out at https://blogs.perficient.com/2019/03/27/simple-markdown-documentation-for-your-aem-components/


My Approach is slightly different, I used client side javascript to read README file, convert to HTML and showing as popup.






It checks if there are external url then it uses those and if there are internal file then only it uses readme file.

Disadvantage 

The code is rely on third party js i.e. https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js

Although this is loaded at run time from cdn


Code

The example component and clienltlibs are at github

clienltlibs

Sample dialog example


Readme file

AEMaaCS - Authoring - Asset Selector in Dialog

Asset Selector

The asset selector lets you browse, search, and filter assets in Adobe Experience Manager Assets. You can also fetch the metadata of assets that you select using the asset selector. To customize the asset selector interface, you can launch it with supported request parameters. These parameters set the context of the asset selector for a particular scenario.

Contextual Parameters - https://experienceleague.adobe.com/docs/experience-manager-64/assets/managing/asset-selector.html?lang=en#contextual-parameters 

You can pass the request parameters in a URL to launch the asset selector in a particular context.

Here we are interesting only in dialog parameter

i.e. http://localhost:4502/aem/assetpicker.html?dialog=true

Use these parameters to open the asset selector as Granite Dialog. This option is only applicable when you launch the asset selector through Granite PathField, and configure it as pickerSrc URL.

I and others tried using this in a dialog but unfortunately it does not work. and A lot people queried about it to make it work.

  • https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/how-to-use-the-aem-asset-selector-in-a-dialog/m-p/265970
  • https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/how-to-use-asset-selector-in-dialog-aem-6-4/m-p/294065#M18413

I tried fixing this problem and now it work with dialog as well. In below section, I have explained what I have tried.


Asset selector in Dialog

1. Used pickerSrc URL as /libs/dam/gui/content/assetselector/jcr:content/body/items/assetselector.html?dialog=true, this will allow to see picker popup but when you select as assets and click on select button, nothing happens.





2. To fix select button problem in point 1, a small javascript written which get the value from picker to dialog and close the picker

(function (document, $) {
    "use strict";

    const PICKER_FORM = 'form.granite-pickerdialog-content';
    const PATHFIELD_TARGET = '.pathfield__asset--selector';
    const MULTIPLE = 'multiple';
    const CLICK = 'click';
    const SELECTORS = {
        SELECT_BTN: PICKER_FORM + ' button.asset-picker-done',
        CANCEL_BTN: PICKER_FORM + ' button.asset-picker-clear',
        SELECTED_ITEM: PICKER_FORM + ' .foundation-selections-item.is-selected',
        ITEM_ATTR: 'data-foundation-collection-item-id',
        PATHFIELD_SELECTOR: PATHFIELD_TARGET + ' input[aria-controls="asset-selector-launcher-setting"]',
        PATHFIELD_MULTI_SELECTOR: PATHFIELD_TARGET + '[multiple] input[aria-controls="asset-selector-launcher-setting"]',
        MODE_ELEMENT: PICKER_FORM + ' #cq-damadmin-admin-assetselector-collection',
        MODE_ATTR: 'selectionmode',
        CORAL_TAGLIST: 'coral-taglist'
    };

    $(document).on(CLICK, SELECTORS.SELECT_BTN, function () {
        var mode = document.querySelector(SELECTORS.MODE_ELEMENT).getAttribute(SELECTORS.MODE_ATTR);
        if (mode === MULTIPLE) {
            var selectedItems = document.querySelectorAll(SELECTORS.SELECTED_ITEM);
            var tagList = $(SELECTORS.PATHFIELD_MULTI_SELECTOR).closest(PATHFIELD_TARGET).find(SELECTORS.CORAL_TAGLIST);
            for (const item of selectedItems) {
                var value = item.getAttribute(SELECTORS.ITEM_ATTR);
                var tag = new Coral.Tag().set({
                    value: value,
                    label: {
                        innerHTML: value
                    }
                });
                tagList.append(tag);
            }
        }
        else {
            var selectedItem = document.querySelector(SELECTORS.SELECTED_ITEM).getAttribute(SELECTORS.ITEM_ATTR);
            document.querySelector(SELECTORS.PATHFIELD_SELECTOR).value = selectedItem;
        }
        //closing popup by cancel button click
        document.querySelector(SELECTORS.CANCEL_BTN).click();
    });

})(document, Granite.$);

Now this work absolutely fine.




PathField example

// Asset Selector picker with single mode
<pathfield
jcr:primaryType="nt:unstructured"
granite:class="pathfield__asset--selector"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Browse pathfield"
fieldLabel="Asset Picker 1"
name="./path"
pickerSrc="/mnt/overlay/dam/gui/content/assetselector/_jcr_content/body/items/assetselector.html?dialog=true"
rootPath="/content/dam"/>

// Asset Selector picker with multiple mode and mimetype
<pathfield2
jcr:primaryType="nt:unstructured"
granite:class="pathfield__asset--selector"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Browse pathfield"
fieldLabel="Asset Picker - Multiple"
name="./path2"
multiple="{Boolean}true"
pickerSrc="/mnt/overlay/dam/gui/content/assetselector/_jcr_content/body/items/assetselector.html?dialog=true&amp;mimetype=*png&amp;mode=multiple"
rootPath="/content/dam"/>

// Default picker
<pathfield3
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Browse pathfield"
fieldLabel="Defualt Picker"
name="./path3"
rootPath="/content/dam"/>




Github

Sample Component
ClientLibs

Note : This fix has been implemented and tested only in AEM as a cloud service instance.


Asset Selector Picker vs Default Picker

Asset Selector gives option to serach and filter, whereas default picker is just allow you to navigate and select in a tree

Asset Selector


Default Picker







AEM - Authoring - Multifield counter

Multifield component allows to add/reorder/remove multiple instances of a field.

In the simplest case this is a simple form input field (e.g. textfield, textarea) but it can also be a complex component acting as an aggregate of multiple subcomponents 


I created a simple dialog which has textfield and pathfield types as subcomponents and look like below in the diagram.I have also authored this with 5 multifield items which are shown in below. 

Can you see all 5 items? Answer is No and to see all 5 you need to scroll down in the form. 

The current design does not gives hint of how many items are there and where individuals item is starts and ends. If the multifield item has many field then it is difficult for Author to visualise this.





Lets write few line of CSS to make it better for readability. Looks better than previous.






With nested multifield




CSS Code

.cq-Dialog coral-multifield coral-multifield-item:not(:first-child){
border-top:2px solid gray;
margin-bottom:10px;
margin-top:20px;
}

.cq-Dialog coral-multifield coral-multifield-item:first-child{
margin-bottom:10px;
margin-top:-10px;
}

.cq-Dialog coral-multifield coral-multifield-item:last-child{
margin-bottom:0px;
margin-top:20px;
}

.cq-Dialog coral-multifield coral-multifield-item .coral3-Multifield-remove,
.cq-Dialog coral-multifield coral-multifield-item .coral3-Multifield-move,
.cq-Dialog coral-multifield coral-multifield-item coral-multifield-item-content{
padding-top:20px
}

.cq-Dialog coral-multifield coral-Multifield-item::before{
content: attr(aria-label);
font-size:1rem;
background-color:lightgray;
color:#919191;
padding:0 10px ;
}


If you want to apply this change to all of the component then create a clientlibs of category cq.authoring.dialog otherwise use exraClientlibs

Above CSS Clientlibs at GitRepo - clientlib-dialog-multifield-decoration

This is tested only in AEMaaCS, this should work in other AEM version as well if coral-multifield-item contains aria-label attribute otherwise you can use CSS counters. e.g. https://github.com/arunpatidar02/aem63app-repo/blob/master/forum/multifield.number.css 


AEM - Authoring - Page Status Visualisation



The AEM sites console http://localhost:4502/sites.html/content can list the AEM pages in List, Column and Card view.

Column View



To check the page status for example if the page is published or not, you need to click on individual page. Due to that the overall pages status in not visible in a glance.


Maximum number of AEM user use this view to navigate through the pages.


Card View

Card view at other hand gives you more information as compare to Column view like locked and Publish/not publish




List View

List view provide more information and option to add/remove columns via settings




but none of the view gives more accurate information like 
if the page is unpublished that means is it never published or unpublished later? 
Whether the page is modified after the publish or before the publish?

And it is impossible to get all this information visually.


What can be done to improve visualisation

The inspiration can be taken from classic UI to show color indicators  or something new can be introduce.
At https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager-ideas/published-status-visualization/idc-p/461069 some ideas are proposed, If Adobe bring this change would be good for Authors

One of the idea which I implemented as part of PoC looks like 


The color/icon indicators represent the following

 Page is published, after publish no modifications are took place

This page is locked

 Page is unpublished, after unpublish no modifications are done

         Page is published, after publish modifications are took place

 Page is published and locked, after publish no modifications are took place

 This page is locked and modified 

 Page is published and locked, after publish modifications are done.


I am not an UX expert but this is just an attempt to implement the concept of visualisations 


PoC Implementation  

The implementation is done only for column view in this PoC, this is done in AEM as a cloud service, so may not work in other version of AEM

  • The sites column view is generated by /libs/wcm/core/content/sites/jcr:content/views/column resource 
  • The children resources for column collected by /libs/wcm/core/content/sites/jcr:content/views/column/datasource, 
  • The column item rendering is done by /libs/cq/gui/components/coral/admin/page/columnitem 


To add the extra status in column view item response
  • /libs/wcm/core/content/sites/jcr:content/views/column/datasource has to be overlay 
  • New column item renderer need to be created similar to /libs/cq/gui/components/coral/admin/page/columnitem  
  • Add CSS to style the visualisation. 

1. Create Custom columnitem resource

copy /libs/cq/gui/components/coral/admin/page/columnitem in apps e.g. /apps/custom/columnitem
update the columnitem.jsp at /apps/custom/columnitem/columnitem.jsp to add following line of code after  line progressTracker.log("completed lastModified handling");
make sure you have opened and closed JSP tags properly. 

// Adding new property START
            Resource jcrItem = resource.getChild(JcrConstants.JCR_CONTENT);
String replicationAction = "";
boolean lockStatus= false;
boolean lastModifiedStatus = false;

            if(null !=jcrItem){
                ValueMap vm = jcrItem.getValueMap();
                replicationAction = vm.get("cq:lastReplicationAction", String.class) != null ? vm.get("cq:lastReplicationAction", String.class)  : "false";
                lockStatus = vm.get("jcr:lockOwner") != null  ? true : false;

                Calendar createdDate = vm.get("jcr:created",Calendar.class);
                Calendar lastModifiedDate = vm.get("cq:lastModified",Calendar.class);
                Calendar lastlastReplicatedDate = vm.get("cq:lastReplicated",Calendar.class);

                if(lastlastReplicatedDate != null && lastModifiedDate !=null){
                    lastModifiedStatus = lastModifiedDate.getTimeInMillis() > lastlastReplicatedDate.getTimeInMillis() ? true : false;
                }
                else if(createdDate != null && lastModifiedDate !=null){
                    lastModifiedStatus = (int) lastModifiedDate.getTimeInMillis()/1000 > (int) createdDate.getTimeInMillis()/1000 ? true : false;
                }
            }

%>
<div class="coral-columnview-item-extra-status">
<% if(lockStatus){%>
  <coral-icon size="S" icon="lockOn"></coral-icon>
<% }
    if(replicationAction.equals("Activate")){%>
        <coral-icon size="S" icon="globeCheck"></coral-icon>
        <% }
    if(replicationAction.equals("Deactivate")){%>
      <coral-icon size="S" icon="globeRemove"></coral-icon>
        <%}
if(lastModifiedStatus){%>
  <coral-icon size="S" icon="edit" content="<%= lastModifiedStatus %>"></coral-icon>
<% }%>
</div>
<% // Adding new property END 

2. Overlay 

Overlay /libs/wcm/core/content/sites/jcr:content/views/column/datasource to /apps/wcm/core/content/sites/jcr:content/views/column/datasource

copy the all the properties of /libs/wcm/core/content/sites/jcr:content/views/column/datasource to /apps/wcm/core/content/sites/jcr:content/views/column/datasource

update the itemResourceType  property to use custom columnitem created in Step1 



2. CSS/Styling 

Create an clientlibs of category cq.listview.coral.columns.personalization only for css e.g. /apps/custom/author/clientlib-sites-color

create color.css with following css rules

.coral-columnview-item-extra-status{
    order: 1;
}

.coral-columnview-item-extra-status coral-icon{
    height:40px;
}

.coral-columnview-item-extra-status ~ svg._coral-AssetList-itemChildIndicator{
    margin-right: 10px;
}

.coral-columnview-item-extra-status [icon="edit"]{
    background-color: #cfe4ec;
    color: #2466b3;
}

.coral-columnview-item-extra-status [icon="lockOn"]{
    background-color: #a39f9f;
    color: #746f6f;
}

.coral-columnview-item-extra-status [icon="globeCheck"]{
    background-color: #8ed58ea8;
    color: #1e481e;
}

.coral-columnview-item-extra-status [icon="globeRemove"]{
    background-color: #eac1c1;
    color: #b23232;
}



Sample package to try this in local (only for AEMaaCS)


Conclusion 

People with access to an AEM author should be able to be quick in recognizing a node as “never published”, “published”, “unpublished”, “modified” and/or “locked”. 
If the three view modes would be enriched with colours a user would immediately see what status a node is in. Imagine if such colours: red = unpublished, green = published, blue = modified, grey = locked, no colour = never published. 

Although the implementation should be done by Adobe to de-risk the future update impact on overlaying and using custom renderer.

AEMaaCS - Touch UI Dialog Dynamic Dropdown

 

Populate Touch UI Dropdown Dynamically based on Other Field


In AEM touch UI, the dropdown options can be populated using static fields or using datasource but the dropdown options are static. Let's say I need to create a dropdown for state and the state values should populate based on country, In this case above two methods will not work. but this can be achieved using dialog listeners. 

This blog is about an example to populate second dropdown options based on the first dropdown.

Steps

1.  Create the first dropdown and populate the options either with fixed values or from datasource. add a granite class to listen to the changes.     

<contenttype
 granite:class="dropdownfield_contenttype"
 jcr:primaryType="nt:unstructured"
 sling:resourceType="granite/ui/components/coral/foundation/form/select" 
 fieldDescription="The type of the content"
 fieldLabel="Content Type"
 name="./type">
 <datasource
  jcr:primaryType="nt:unstructured"      sling:resourceType="aemlab/dialog/granite/components/select/datasource/content/type"/>
</contenttype>


2. Create a second dropdown without any options and add a granite class            
 
<contentsubtype
  granite:class="dropdownfield_contentsubtype"
  jcr:primaryType="nt:unstructured"           sling:resourceType="granite/ui/components/coral/foundation/form/select"
  fieldDescription="The subtype of the content"
  fieldLabel="Content SubType"
  name="./subtype"/>



3. Create a hidden field for the second dropdown to repopulate pre-saved value on a dialog load. The name property must be the same as the secondary dropdown and this field must be disabled and hidden.
                                 
<contentsubtype-hidden                         granite:class="dropdownfield_contentsubtype--hidden"
 jcr:primaryType="nt:unstructured"
 sling:resourceType="granite/ui/components/coral/foundation/form/hidden"
 disabled="{Boolean}true"
 name="./subtype"/>



4. Create Clientlibs(javascript) to populate the second dropdown based on the first dropdown value. The values of the second dropdown can be populated based on any business logic. 

Here I am calling a servlet /apps/aemlab/concept/utils/dialog/contentsubytpe.json with the first dropdown value and getting the options for the second dropdown.

     const contentTypeSelector = ".dropdownfield_contenttype";
    const contentSubTypeSelector = ".dropdownfield_contentsubtype";
    const contentSubTypeDataSourceUri =
        "/apps/aemlab/concept/utils/dialog/contentsubytpe.json";

    $document.on("foundation-contentloaded", function (e) {
        setSubTypeDropdown(true);
    });

    $document.on("change", contentTypeSelector, function (e) {
        setSubTypeDropdown(false);
    });

    function setSubTypeDropdown(preSelect) {
        const contentType = document.querySelector(contentTypeSelector);
        const contentSubType = document.querySelector(contentSubTypeSelector);

        if (contentType && contentSubType) {
            var url =contentSubTypeDataSourceUri +"?type=" +contentType.value +"&ck=" +Math.random();
            $.get(url, function (data) {
                updateSubTypeDropdownField(preSelect, data);
            });
        }
    }

Complete Javascript Code at  

Dialog


dialog


GitHub

All the code and component example are available at 
Component : 
https://github.com/arunpatidar02/aemaacs-aemlab/tree/master/ui.apps/src/main/content/jcr_root/apps/aemlab/oneweb/concept/components/dropdown-dynamic
Secondary Dropdown Source Path :
https://github.com/arunpatidar02/aemaacs-aemlab/tree/master/ui.apps/src/main/content/jcr_root/apps/aemlab/oneweb/concept/utils/dialog/contentsubytpe
First Dropdown datasource and secondary dropdown Servlet :
https://github.com/arunpatidar02/aemaacs-aemlab/tree/master/core/src/main/java/com/community/aemlab/oneweb/core/servlets/ds
The above code is tested in AEM as a Cloud Service, but it will work with standard AEM as well.

AEM - Touch UI - Multifield - Coral2 JSON store to Coral3 node store conversion


In Touch UI, Coral2 multifield with ACS common allow multifield data to stored as JSON but when you are going to migrate to Coral3/Granite type, new Granite type store multifield data in nodes not in JSON.

If the dialogs are already authored and if you convert them to Granite type then multifield dialogs fields would not be prepopulated without already authored data.

There are multiple solutions to pre-populate multifield fields with json data, the one is to create node structure from json.

In this article, I will show one of the approaches, to convert json data to node data.

Suppose if the dialog has a multifield item like below :
https://github.com/arunpatidar02/aem63app-repo/blob/master/packages/tmp/dialog-snippet1.xml

after dailog authored the values are stored in a json format.



                                     
To make the above dialog compatible with coral3, the data should be stored in a node under iItems. like below:


Note: The dialog fields should be changed separately from coral2 to coral3 resourcetype.

The below servlet runs SQL2 query and look for the touchmulti component and convert json data to nodes, so it will be compatible with coarl3 multifield and prepopulate the authored data.


Code :
https://github.com/arunpatidar02/aem63app-repo/blob/master/java/MultifieldConvertCoral2to3Servlet.java

AEM - Touch UI Dialog - Display fields in a same row | Two Column Layout

In Touch UI dailog Coral/Granite type fields displays in a stack/top to bottom, one after another in a floating dialog and in fullscreen. In fullscreen it can be displayed in 2 column layout if column layout is used for dialog (columns inside granite/ui/components/foundation/layouts/fixedcolumns type )





and It will show fields in dailog like below:

Floating mode and Fullscreen mode





Improve Authoring Experience

Visit https://experiencemanaged.com/posts/improve-the-aem-authoring-experience-ax.html blog to see how authoring experience can be improved.


There are several scenarios where having a top-to-bottom approach to all fields can have a negative impact on the authoring experience. To improve the experience, fields can be added one after another in the same row.

How to do it

  • Create clientlibs from code mentioned in ClientLibs Code section
  • Add rowresume (Boolean) = true property in the field to display field in the same row. Make sure this property is added in all the fields which should display in the same row.

rowresume property

  • Add rowresume property in the field, if Coral2 type is used 
  • if you are using coral3/Granite type then add rowresume property in granite:data node


'rowresume' Coral2 resource type


'rowresume' Granite/Coral3 resource type

ClientLibs Code 

  1. Create a clientlibs of category 'cq.authoring.dialog'
  2. Create js.txt , css.txt, dialog.field.2column-layout.css and dialog.field.2column-layout.js files with below content or click on the file name to get the file from Github.

js.txt
dialog.field.2column-layout.js

dialog.field.2column-layout.js

(function($, $document) {
    "use strict";
    $document.on("dialog-ready", function() {
        var items = $('[data-rowresume="true"]');
        $(items).each(function(i) {
            $(this).closest('.coral-Form-fieldwrapper').addClass("coral-Form-fieldwrapper--rowresume");
        });
    });

})($, $(document));

css.txt
dialog.field.2column-layout.css

dialog.field.2column-layout.css
.coral-Form-fieldwrapper.coral-Form-fieldwrapper--rowresume {
    width: 44%;
    display: inline-grid;
    margin: 0 3%;
}


Dailog fields after adding rowresume property to width, height, dropdown and radio group fields


Fullscreen mode


Dailog fields after adding rowresume property to height, dropdown and radio group fields


Package

You can install below packages from GitHub to enable this feature for touch ui dialog. These works in AEM 6.3+


However, packages contain:
1. Clientlibs to enable side panel option in touch ui dialog.
2. Clientlibs to enable displaying touch ui field in two-column layout in floating touch UI dialog


If you install this package, Below files will be installed in the repository at 

  • /apps/commons/clientlibs/dialog/js.txt
  • /apps/commons/clientlibs/dialog/js/dialog.field.2column-layout.js
  • /apps/commons/clientlibs/dialog/css.txt
  • /apps/commons/clientlibs/dialog/css/dialog.field.2column-layout.css


Other files are getting used to enable side panel option in touch ui dialog, Find more details about it at AEM - Touch UI Dialog - Assets Panel


Limitation:

Work only with form field type.

AEM - Touch UI Dialog - Assets Panel

In Touch UI dailog when we use file upload type e.g. cq/gui/components/authoring/dialog/fileupload or granite/ui/components/foundation/form/fileupload field to allow authoring assets from the side panel.
In order to author the images, side panel should be opened before editing via dialog.



AEM Page editor with side panel and dialog opened



Authoring image using drag and drop


If you forgot to open the side panel before opening the dialog then you need to close the dialog, open side panel and open the dialog again to author assets.





This is kind of annoying to close the dialog and open it again just to author images/Assets. 
Why can't the side panel open from the dialog without closing the dialog?


That's it, here you go -


Side panel toggle button in dialog header





side panel toggle from dailog



How to do it

This can be achieved by simply adding a side panel toggle button in the dialog header alongside help or other buttons. When clicking on this button, the click event will be triggered on the actual side panel toggle button and rest will be OOTB.
  1. Create a clientlibs of category 'cq.authoring.dialog'
  2. Create js.txt and dialog.sidepanel.js files with below content or click on file name to get file from github.


js.txt
dialog.sidepanel.js

dialog.sidepanel.js


(function($, $document) {
    "use strict";
    var flag = true;
    $document.on("dialog-ready", function() {

        var buttonHTML = '<button is="coral-button" icon="railLeft" variant="minimal" class="cq-dialog-header-action cq-dialog-railLeft coral-Button" type="button" title="Toggle Side Panel" size="M">';
        buttonHTML += '<coral-icon class="coral-Icon coral-Icon--sizeS coral-Icon--railLeft coral3-Icon--railLeft" icon="railLeft" size="S" role="img" aria-label="rail left"></coral-icon>';
        buttonHTML += '<coral-button-label></coral-button-label>';
        buttonHTML += '</button>';

        $('.cq-Dialog coral-dialog-header.cq-dialog-header>div.cq-dialog-actions > button:nth-child(1)').after(buttonHTML);

        if (flag)
            $(document).on('click', 'button.cq-dialog-railLeft', toggleLeftRail);

        function toggleLeftRail() {
            flag = false;
            $('.editor-GlobalBar coral-actionbar-primary coral-actionbar-item button.toggle-sidepanel').click();
        }

    });

})($, $(document));



Or For AEMaaCS

https://github.com/arunpatidar02/aemaacs-aemlab/blob/master/ui.apps/src/main/content/jcr_root/apps/aemlab/oneweb/concept/clientlibs/author/clientlib-dialog-sidepanel-toggle/js/dialog.sidepanel.js 

Package

You can install below packages from GitHub to enable side panel option in touch ui dialog. These works in AEM 6.3+


However, packages contain:
1. Clientlibs to enable side panel option in touch ui dialog.
2. Clientlibs to enable displaying touch ui field in two-column layout in floating touch UI dialog


If you install this package, Below files will be installed in the repository at 

  • /apps/commons/clientlibs/dialog/js.txt
  • /apps/commons/clientlibs/dialog/js/dialog.sidepanel.js


Other files are getting used to showing field in the same row, more details at https://aemlab.blogspot.com/2019/07/aem-touch-ui-dialog-fields-in-same-row.html.
  • /apps/commons/clientlibs/dialog/js/dialog.field.2column-layout.js
  • /apps/commons/clientlibs/dialog/css.txt
  • /apps/commons/clientlibs/dialog/css/dialog.field.2column-layout.css