Thursday, February 18, 2016

AEM Touch UI : Increasing the Author Dialog width & Height with CSS

The author dialog in Touch UI will look smaller and don't have the option to set width & height in the properties like Classic UI dialogs. But this can be fixed by overriding the CSS under your apps clientlib folder. I'm not covering here the steps for creating the clientlib. The style that needs to be added in the CSS is as follows:

/*changes author dialog box size*/
.cq-dialog-floating {
width:70%;
height:80%;
overflow:auto;
}

/*.cq-dialog-floating .coral-TabPanel-content*/
.cq-dialog-floating .cq-dialog-content.coral-TabPanel > .coral-TabPanel-content, .cq-dialog-floating .cq-dialog-content > .coral-TabPanel > .coral-TabPanel-content {
height:90% !important;
padding-bottom: 7rem !important;  /*just to fix the drop down box clipping inside */
overflow: hidden !important;
}

.cq-dialog-floating .coral-FixedColumn-column {
width:90%;
height:100%;
}

Thursday, January 14, 2016

AEM: Removing Wrapper element of a component only in preview mode with out disturbing its edit feature.

There were many ways to remove the wrapper in all the modes. But, doing that will hide the authoring feature in the edit mode. Also, these wrappers will not appear in the publish instance. So, it is not actually required for the authors who are running the author & publish instance side by side to checking their content updates. But, my script will save some publishing time for authors & view their actual design in the preview mode of author instance.

I could find many examples for removing the wrapper element completely in all mode, few options are here,

1. Under cq:Component, add the property cq:noDecoration = true. or
2. Under cq:Component, create a node cq:htmlTag as nt:unstructured & add the property cq:tagName = ""

Now, let see the solution for unwrapping the element only in the preview mode.

The following code is created by AEM for a simple button component named as custom_button & remember this is a sightly component.


I have the javascript file as listener added to my head.html in the base template & it is the base template for all other templates. It makes the JS loaded in all other templates.
----------------------------------------------------------------------------------------------------------------------
      var unWrapElementInPreviewMode= function() {
$('iframe').bind("load",function(){
    //check if button component exists
    var $unWrapSelector = $(this).contents().find('a.x-button');
if($unWrapSelector.length){
$(document).on("click", ".js-editor-LayerSwitcherTrigger", function () {
if($.cookie('wcmmode') == "preview") {
$unWrapSelector.each(function(index,val){
$(this).unwrap();
});
}else{
location.reload();
}
});
}

   });
};

$(document).ready(function() {
//refresh page while shifting between Edit and Preview Mode
unWrapElementInPreviewMode();
});


---------------------------------------------------------------------------------------------------------------------

($.cookie('wcmmode') == "preview" - finding the wcmmode. You can see my previous post that covers this in detail. 

click listener triggers while clicking the edit or preview button. unwrap() removes the parent element of the selectors and then I'm just reloading the page in edit mode to get my wrapper back. This might add some loading time while shifting from preview to edit mode. 

Wednesday, January 13, 2016

AEM: How to find WCMMode in Jquery/ Javascript

WCMMode can be captured in Sightly or Java code as follows

In Sightly,

<div data-sly-test.author="${wcmmode.edit || wcmmode.design || wcmmode.preview}">

In Sightly Java code that extends WCMUse ,

getWcmMode().isEdit(), getWcmMode().isDesign() or getWcmMode().isPreview()

But, finding this in Jquery or Javascript is not straight forward. We need to make use of the cookies like

if($.cookie('cq-editor-layer') == "Preview") {
console.log("Preview Mode");
}else if ($.cookie('cq-editor-layer') == "Edit") {
       console.log("Edit Mode");
}

or

if($.cookie('wcmmode') == "preview") {
console.log("Preview Mode");
}else if ($.cookie('wcmmode') == "edit") {
       console.log("Edit Mode");
}

Also, you can find the AuthoringUIMode is touch or classic with the cookie

if($.cookie('cq-authoring-mode') == "Touch") {
console.log("Touch UI");
}else if($.cookie('cq-authoring-mode') == "Classic") {
console.log("Classic UI");
}

Tuesday, January 12, 2016

AEM: Reloading page while switching between edit and preview mode.

It is simple to reload the page in the edit mode after adding or updating the component properties in the dialog box. It can be easily achieved by adding actions like afteredit,afterinsert under cq:EditConfig > cq:listeners. Refer the following link https://docs.adobe.com/docs/en/cq/5-6-1/developing/components.html

This post is to cover the page reload action while switching between edit  & preview mode which is not a default action in AEM 6. It is good for authoring experience that reduces lot of waiting time for loading the page every time while switching the WCM modes. But, some time it is important when we use some javascript or css that is added to the component only in the preview mode.

Add the below script to a JS file and include this in your base template html & make it available for all the other templates.

var enablePreviewRefresh = function() {
$('iframe').bind("load",function(){
    //check for a specific component which requires page reload, so that we can avoid invoking the listener for all the component.
    var $selector = $(this).contents().find('div.q-specific-component');
if($selector.length) {
$(document).on("click", ".js-editor-LayerSwitcherTrigger", function () {
location.reload();
});
}
   });
};

$(document).ready(function() {
//refresh page while shifting between Edit and Preview Mode
enablePreviewRefresh();
});

js-editor-LayerSwitcherTrigger is the class used on the mode changing buttons.  So, you can add the listeners and scripts to achieve any actions.

Monday, January 11, 2016

Customizing the default parsys text of AEM using Sightly code

I got a requirement to change the default placeholder text "drag component here" of parsys component to show customized text for each different component that includes it through the sightly script. 


One way of changing the default text all over the place is editing/overriding the script in /libs/cq/gui/components/authoring/clientlibs/editor/js/model/Inspectable.js. It would change the text everywhere in the parsys.  But, I wanted to customize this text for each component and it can be achieved with the following steps

Step 1: Override the parsys from the out of the box AEM to your apps folder ie wcm/foundation/components/parsys. 

The new sightly component is placed in the /libs/wcm/foundation/components/parsys.

Step 2: Add the property "sling:resourceSuperType" and the value "wcm/foundation/components/parsys" at the component level or the .content.xml. The code will look like
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root 
    xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
    xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="Paragraph System - Sightly"
    jcr:description="Include components in a paragraph system."
    allowedChildren="[*]"
    componentGroup=".hidden"
    sling:resourceSuperType="wcm/foundation/components/parsys"/>

Step 3: Select the newpar component folder inside this component and add the property sling:resourceType with the value "wcm/foundation/components/parsys/newpar". This code will look like
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="New Paragraph - Sightly"
    sling:resourceType="wcm/foundation/components/parsys/newpar"
componentGroup=".hidden"/>

Step 4: The default text can be set empty by making the following change. Open the parsys.html files change this line 

<div data-sly-test="${!paragraph.columns && paragraph.resourceType && paragraph.cssClasses}" class="${paragraph.cssClasses}" data-sly-resource="${paragraph.resourcePath @ resourceType=paragraph.resourceType, decorationTagName=''}"></div> to 

<div data-sly-test="${!paragraph.columns && paragraph.resourceType && paragraph.cssClasses}" class="cq-placeholder section" data-emptytext=""  data-sly-resource="${paragraph.resourcePath @ resourceType=paragraph.resourceType, decorationTagName=''}"></div>

That's all required in the overridden/extended parsys component. Now, we need to add some code in our new components that includes the parsys.

Step 5: Create a new component and use the following code for adding the placeholder text is  <div class="cq-placeholder section" data-emptytext="Your Custom Text"></div> 

The sighlty code for including any component would be like <sly data-sly-resource="${'myComponents' @ resourceType='/apps/yourProject/parsys' }"></sly> 

Note: the resourceType would point to the folder where our parsys component is created.