Expand my Community achievements bar.

SOLVED

Automatically apply selected style to component?

Avatar

Level 1

In AEM 6.0 SP2, when using the touch UI on a component that uses the "Component Styles" functionality, the component does not apply the new class to the component until after a page refresh.  To reproduce this issue:

  • Go to the "Discover Geometrixx" sample page (http://localhost:4502/editor.html/content/geometrixx/en/company/discover_geometrixx.html)
  • Select the Text/Image component that says "Geometrixx was founded in 545..."
  • Click the dialog "wrench" icon
  • In the Component Styles tab, change the image alignment from "Left" to "Right"
  • Close the dialog with the "check mark" icon
  • Observe that the image alignment did not change
  • NOTE: You can see in a network trace that the component is refreshed from the server as an ajax call (GET textimage_0.html...), and the class "image_right" is added to the parbase div in the response HTML.  However, if you then inspect the DOM, you'll see that for some reason the "image_right" class is no longer applied to the parbase div after it is updated in the DOM.  This happens in latest Chrome and in IE 11.
  • Refresh the page
  • Observe that the image alignment now shows correctly

This is happening in our new site as well with our own custom components that use the Component Styles dialog functionality and it is very annoying for authors.  The only work-around we've found is to add a cq:listeners to refresh the page automatically, but this is a very poor work-around since unless the component is at the top of the page, the author has to scroll back to where they were editing.  Is there a work-around or a patch to fix this issue so in-place update of the component style works without full page refresh?

1 Accepted Solution

Avatar

Correct answer by
Level 7

Hi,
In OOTB componentof "text-image"  when you update the direction field value of the dialog,at run time there will be ajax call and page is refreshed.
Then the functionality will appear on the page.
So i updated my custom component without calling ajax call and takes value from the dialog and set it into the code below.

String divId = "cq-textimage-jsp-" + resource.getPath(); String imageHeight = image.get(image.getItemName(Image.PN_HEIGHT)); String direction=properties.get("selectdirection",""); // div around image for additional formatti if(direction.equals("image_right")){ %><div class="image" style="float:right;margin:0 8px 8px 0;"id="<%= xssAPI.encodeForHTMLAttr(divId) %>"><%} else if(direction.equals("image_left")){ %><div class="image" style="float:left;margin:0 8px 8px 0;"id="<%= xssAPI.encodeForHTMLAttr(divId) %>"><%} image.draw(out); %><br></div><% %><cq:text property="image/jcr:description" placeholder="" tagName="small" escapeXml="true"/>

From the below image you can see the updated values.

 Node name:componentstyle
 Name:name
 Type:String
 Value:./selectdirection

[img]imagedirection.PNG[/img]

View solution in original post

2 Replies

Avatar

Correct answer by
Level 7

Hi,
In OOTB componentof "text-image"  when you update the direction field value of the dialog,at run time there will be ajax call and page is refreshed.
Then the functionality will appear on the page.
So i updated my custom component without calling ajax call and takes value from the dialog and set it into the code below.

String divId = "cq-textimage-jsp-" + resource.getPath(); String imageHeight = image.get(image.getItemName(Image.PN_HEIGHT)); String direction=properties.get("selectdirection",""); // div around image for additional formatti if(direction.equals("image_right")){ %><div class="image" style="float:right;margin:0 8px 8px 0;"id="<%= xssAPI.encodeForHTMLAttr(divId) %>"><%} else if(direction.equals("image_left")){ %><div class="image" style="float:left;margin:0 8px 8px 0;"id="<%= xssAPI.encodeForHTMLAttr(divId) %>"><%} image.draw(out); %><br></div><% %><cq:text property="image/jcr:description" placeholder="" tagName="small" escapeXml="true"/>

From the below image you can see the updated values.

 Node name:componentstyle
 Name:name
 Type:String
 Value:./selectdirection

[img]imagedirection.PNG[/img]

Avatar

Level 1

Thanks Techaspect.  I had considered doing a work around like that, but it is happening on several components and I didn't want to rewrite the server logic for all of them to include the component styles, which should be applied automatically (and is applied on page load, just not on an AJAX update of the component).  However, I was able to track down the client script that was causing the problem.  In libs/cq/gui/components/authoring/clientlibs/editor/js/edit/edit.actions.js, in the _updateDom function, it appears to have some code that deals with “legacy” class information based on the component type.  It overrides the class attribute that was returned by the ajax call.  It sets it to “section” plus those classes defined by the component type, but does not include the class from the component style setting.  I changed the following line (line #102) from:

val = 'section ' + val;

to:

val = 'section ' + val + ' ' + domElem.attr(attr);

to preserve the classes returned from the server (including the component styles selection).  It ends up having some duplicate names in the class, but it works.  NOTE: I made this change by creating an “overlay” in the apps tree and modifying the js file there.  There may be a cleaner way to do this, like finding the component style class(es) somewhere in metadata, but this works and only results in duplicate names in the class attribute when authoring.  In any case, this seems like a bug in the edit.actions.js code.