Ad Code

Sunday, January 27, 2019

cq:dropTagets in cq:editConfig Node in AEM


Hello Everyone,

In the previous blog, we already talk about one of the child node of cq:editConfig
which is cq:listeners.

In this blog, we will talk about “cq:dropTargets” feature of “cq:editConfig” node.
cq:dropTargets(of type nt:unstructured) is the child node of cq:editConfig
(of type cq:EditConfig) node and defines a list of drop targets that can accept a drop from an
asset of the content finder as shown in the image below.It serves as a collection of
nodes of type cq:DropTargetConfig.
Fig:1- Assets in content finder

Note:
  • Multiple drop targets are only available in the classic UI.
  • In the touch-enabled UI, a single drop target is allowed.

Each child node of type cq:DropTargetConfig defines a drop target in the component.
The node name was so fix till AEM 6.2, but as now from AEM 6.3, the node name is
so flexible and we can use any nodenam,still we will try to use nodename as
OOTB components are using.

The node of type cq:DropTargetConfig needs to have the following properties:
Property Name
Property Value
accept
Regex applied to the asset mime type to validate if dropping is allowed.
groups
Array of drop target groups. Each group must match the group type that is defined in the content finder extension and that is attached to the assets.
propertyName
Name of the property that will be updated after a valid drop.

Why to use dropTargets in a component??

It is not really necessary to use dropTarget as you can configure image,video after opening the dialog, but it is good to use feature if without opening dialog, you can just drag and drop the image from the content finder inside the dialog.

So personally, I would like to go with this feature for every possible component where I can use it.

So question comes here, in which components we can use this feature? We can use this in any component where I can drag and drop any asset using content finder Image,Video,Audio,any component having a page Path configuration etc.

Variations of Drop Targets in a Component
Image Component:
<cq:dropTargets jcr:primaryType="nt:unstructured">
 <image
      jcr:primaryType="cq:DropTargetConfig"
      accept="[image/.*]"
      groups="[media]"
      propertyName="./fileReference">
  <parameters>
      sling:resourceType:”relative path of the component”
  </parameters>
</image>
</cq:dropTargets>

Confusion:I have seen sling:resourceType in the “parameters” node pointing to itself for only image,video and audio dropTargetConfig nodes and what I understood from forums about it is “sling:resourceType as necessary to tell which component is supposed to render the content that gets dragged and dropped.”

My Observation: But my observation is that if you don’t put resourceType also,still things will work fine for image,video and audio components.But I recommend that you use resourceType as it is given in all OOTB Components so there may be situations where it is needed.If i will get to know the use case of adding this property, I will let you know.

Demonstration Video on Drag and Drop functionality of image using cq:dropTargets:


Video Component:
<cq:dropTargets jcr:primaryType="nt:unstructured">
 <video
      jcr:primaryType="cq:DropTargetConfig"
      accept="[video/.*]"
      groups="[media]"
      propertyName="./fileReference">
  <parameters>
      sling:resourceType:”relative path of the component”
  </parameters>
</video>
</cq:dropTargets>

Audio Component:
<cq:dropTargets jcr:primaryType="nt:unstructured">
 <audio
      jcr:primaryType="cq:DropTargetConfig"
      accept="[audio/.*]"
      groups="[media]"
      propertyName="./fileReference">
  <parameters>
      sling:resourceType:”relative path of the component”
  </parameters>
</audio>

Any component having Page Path:
<cq:dropTargets jcr:primaryType="nt:unstructured">
 <pages
      jcr:primaryType="cq:DropTargetConfig"
      accept="[.*]"
      groups="[page]"
      propertyName="./pages"/>
</cq:dropTargets>

Demonstration Video on Drag and Drop functionality of page using cq:dropTargets:
:

Download Component:
<cq:dropTargets jcr:primaryType="nt:unstructured">
 <file
      jcr:primaryType="cq:DropTargetConfig"
      accept="[.*]"
      groups="[media]"
      propertyName="./fileReference"/>
</cq:dropTargets>

Note: In AEM 6.4 fresh instance, cq:dropTargets doesn’t work so you need to add service pack (Service Pack 6.4.2) to the instance. So if you face this issue in any other version so maybe you need to upgrade your AEM instance with service pack.

If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com

Hope it will help you guys !!
Thanks and Happy Learning.

Saturday, January 26, 2019

OOTB/Custom cq:listeners In cq:editConfig Node In AEM

Hello Everyone,

Today In this blog we will talk about cq:listeners in editConfig (node type cq:EditConfig) node in AEM components.The cq:listeners node (node type cq:EditListenersConfig) defines what happens before or after an action on the component.

So you must have been seen many values corresponding to actions (i.e., afterinsert, afterdelete, aftermove,afteredit) of a component.

The following table defines its possible properties:

Properties
Description of each Property
beforedelete
The handler is triggered before the component is removed.
beforeedit
The handler is triggered before the component is edited.
beforecopy
The handler is triggered before the component is copied.
beforeinsert
The handler is triggered before the component is inserted.
beforechildinsert
The handler is triggered before the component is inserted.
Only operational for the touch-enabled UI.
beforemove
The handler is triggered before the component is moved.
afterdelete
The handler is triggered after the component is deleted.
afteredit
The handler is triggered after the component is edited.
aftercopy
The handler is triggered after the component is copied.
afterinsert
The handler is triggered after the component is inserted.
afterchildinsert
The handler is triggered after the component is inserted inside another component (containers only).
aftermove
The handler is triggered after the component is moved..

For nested components, the values of the following properties must be REFRESH_PAGE:

  • aftercopy
  • aftermove

There are some predefined values corresponding to the above listeners  properties:

  • REFRESH_SELF
  • REFRESH_PARENT
  • REFRESH_PAGE
  • REFRESH_INSERTED

The detailed description of the most probably used listener properties has been written below.

REFRESH_SELF: Using this value the component gets refresh before or after the component has been inserted,deleted,edited etc.This is being used when the component is individual and not having any dependency on any component.

REFRESH_PARENT:Using this value the component parent gets refresh before or after the component has been inserted,deleted,edited etc.This is being used when the component is having any dependency on other component like a component A is including other component B in it. So When any actions on B, we can use this option to refresh A also.

REFRESH_PAGE:Using this value the page gets refresh before or after the component has been inserted,deleted,edited etc.Usually people avoid to do this action as every time you are doing any action on a component, if the whole page gets refreshed, then it's so annoying and it takes time for author also to do authoring.
Fig -1 : cq:listeners node in cq:editConfig
The event handler can be implemented with a custom implementation. It means that we can also write our custom methods corresponding to the predefined properties.

For example:
afterinsert="function(path, definition) { this.refreshCreated(path, definition); }"

Here I wanna talk about one problem statement which i faced few days ago regarding listeners.

Problem Statement: There was a container component which includes a parsys and I want to throw an “item component” under the parsys of container component.

There was some min and max for the item components and if author throw less or more components than the expectations, then the container component shows a message like please throw minimum or maximum item components. Now the issue was when author throw item component, it doesn’t refresh the container component.
So the hierarchy is like:
+--container
    +--parsys
       +--item
       +--item
       +--item
So what i tried is, I was trying to REFRESH_PARENT on “item component” cq:listeners but this only refresh parsys but not the container component. Then what to do? So to conclude the problem is I was supposed to refresh the grand parent but not the parent.

Custom Listener to refresh grandparent

I managed to write the logic for classic and touch UI so it can work in both for the same component. So we need to make two clientlibs one for classic (with categories “cq:widgets”) and one for touch (categories “cq.authoring.dialog”). In AEM 6.4, use “cq.authoring.editor” in place of “cq.authoring.dialog”.
Fig -2: Custom listeners
Function to call custom listener from cq:listeners node:
function(path, definition) {
   CQ.Myproject.Component.superParentRefresh(this);
}

Listener for Touch UI:
(function($, ns, channel, window, undefined) {
   "use strict";
   window.CQ.Myproject = window.CQ.Myproject || {};
   window.CQ.Myproject.Component = window.CQ.Myproject.Component || {};
   var superParentRefresh = function(cmp) {
       ns.edit.actions.doRefresh(cmp.getParent().getParent())
       return true;
   };
   window.CQ.Myproject.Component.superParentRefresh = superParentRefresh;
}(jQuery, Granite.author, jQuery(document), this));

Listener for Classic UI:
CQ.Myproject.Component = function() {
   return {
       superParentRefresh: function(cmp) {
           var parent = cmp.getParent();
           parent.getParent().refresh();
       }
   };
}();

Demonstration Video On OOTB/Custom cq:listeners in cq:editConfig node:



If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com

Hope it will help you guys !!
Thanks and Happy Learning.

Wednesday, January 16, 2019

Dynamically Populate Drop Down Values in AEM

Hello Everyone,

You must be thinking that what I am gonna talk about here if there are hundreds of blogs
available over the internet about dynamic drop down. So there are really some things which
might be new to you and this blog won't disappoint you.

There are so many places in AEM project  where we need to dynamically populate
drop down for instance populate the list of pages, populate the country list and so on.
There are two types of use cases which are being used in each and every project.
  • Dynamically populate drop down based on datasource (Build on logic)
  • Dynamically Populate drop down based on values available statically using ACS Commons Generic list. (No logic)
Dynamically Populate Drop Down Based On Datasource

Problem Statement: Let suppose I have a requirement of pulling all the children pages of a root path in drop down.
Solution:
Step 1: Make a drop down widget and create a datasource node under it like this:
Fig -1 Data Source Node Under Select Widget
Step 2: Add a property “resourceType” in datasource which can be mapped to “paths” and “resourceTypes” of the servlet.
Fig -2 Add Resource Type Property In Data Source
Step3: Write a java class mapped to datasource and write a logic to dynamically populate values in the drop down.
sling:resourceType of datasource = sling.servlet.paths of servlet
OR
sling:resourceType of datasource = sling.servlet.resourceTypes of servlet



Note: I have seen people writing a new servlet for every select but actually this is not required. We can get more control on the component if multiple select can use the same service.To make this point clear read the problem statements below and understood how we can solve this.
Let’s discuss few more problem statements:
  • In a project there can be situations where in a component A, you want to pull drop down from Root X and in the component B, you want to pull drop down from Root Y.
Solution: you can add a property may be rootPath in datasource node and fetch the value of that rootPath in the servet and show values.
  • There can be a situation that in component A you want to pull list of pages but in component B you want to pull list of countries.
Solution: You can add a property may be selector as “pageListing” for fetching all the pages or “countryList” to fetch all the countries list and in the servlet call different functions to dynamically populate different values.
Fig -4

Check the code for the above problem statement on github from here.
See the demo video for more visibility over all the problem statements and solutions:

Demonstration Video On How to Populate Drop Down Dynamically Based On DataSource:


Dynamically Populate Drop Down Based On Values Available Statically
Using ACS Commons Generic List

If you are working in AEM platform, you must be aware about ACS Commons and its features and here I am going to describe one feature which is Generic Lists.

Using generic lists, if you have some values and want to populate these values dynamically in drop down you can do. The benefit is if one day author want to add one more value, he can add one more value by himself.

Prerequisites: Your AEM instance must have acs commons package.
Step1: Go to misadmin and select Generic Lists under acs commons.
Step2: Click on New.
Step3: Select generic list template and click on Create.
Step4:Open the page and drag and drop a component named Generic List Item.
Fig -4 

Step5: Add the Title and Value in the Generic List Item component.
Fig -5 Generic List Items
Title: The title which will be visible to the author in drop down.
Value: Value is what gets stored corresponding to what text you selected from drop down. Now values are ready to populate in drop down component.
  • Make a drop down widget and create a datasource node.
  • Add following values in the datasource node.
Fig -6 Data Source Node for using ACS Commons Generic List 
1. sling:resourceType="acs-commons/components/utilities/genericlist/datasource"
2. path="/etc/acs-commons/lists/country-list" //This path is the page path you created earlier and added generic list item.
This is how you can dynamically populate all the values in drop down using generic lists.
Demonstration Video On How to Populate Drop Down Based on Values Available Statically Using ACS Commons Generic List:

If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com


Hope it will help you guys !!
Thanks and Happy Learning.