Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM 6550 - SPA Editor Refresh Component (ReRender) on Dialog Update

$
0
0

Goal

Refresh & Render the SPA component with updated model data when a user adds new content in dialog...

Demo | Package Install | Github




Solution

1) Updating the component is a 2 step process...

                                            a) Trigger a custom event from the SPA editor with latest dialog data...

                                            b)  Listen to the event in component render script and update...


Trigger Custom Event

1) Add a client library to extend editable action EditableActions.REFRESH and pass the updated model in a custom event eaem-spa-component-refresh-event. Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-sites-spa-how-to-react/clientlibs


2) Create node /apps/eaem-sites-spa-how-to-react/clientlibs/clientlib-extensions of type cq:ClientLibraryFolder, add String[] property categories with value [cq.authoring.editor], String[] property dependencies with value lodash.

3) Create file (nt:file) /apps/eaem-sites-spa-how-to-react/clientlibs/clientlib-extensions/js.txt, add

                        refresh-component.js

4) Create file (nt:file) /apps/eaem-sites-spa-how-to-react/clientlibs/clientlib-extensions/refresh-component.js, add the following code

(function($, $document){
var EAEM_COMPONENTS = "eaem-sites-spa-how-to-react/",
EAEM_SPA_COMP_REFRESH_EVENT = "eaem-spa-component-refresh-event";

$document.on("cq-editables-loaded", overrideSPAImageCompRefresh);

function overrideSPAImageCompRefresh(){
var _origExec = Granite.author.edit.EditableActions.REFRESH.execute;

Granite.author.edit.EditableActions.REFRESH.execute = function(editable, config){
if(editable.type.startsWith(EAEM_COMPONENTS)){
$.ajax(editable.slingPath).done(function(compData){
sendComponentRefreshEvent(editable, compData);
});
}

return _origExec.call(this, editable, config);
};
}

function sendComponentRefreshEvent(editable, compData){
let event = new CustomEvent(EAEM_SPA_COMP_REFRESH_EVENT, {
detail: {
type: editable.type,
path: editable.path,
slingPath: editable.slingPath,
data: compData
}
});

window.dispatchEvent(event);
}
}(jQuery, jQuery(document)));



Add Custom Event Listener

5) In the React render script add a listener in componentDidMount() function to check if the event is for this component, update this.props with  latest model data and call this.forceUpdate() to update the component display (without refreshing page...)

import { MapTo } from '@adobe/cq-react-editable-components';
import DOMPurify from 'dompurify';
import React, { Component } from 'react';
import {Link} from "react-router-dom";

const ImageEditConfig = {
emptyLabel: 'Image - Experience AEM',

isEmpty: function (props) {
return (!props || !props.fileReference || (props.fileReference.trim().length < 1));
}
};

class Image extends Component {
componentDidMount() {
//todo check for wcmmode
window.parent.addEventListener("eaem-spa-component-refresh-event", (event => {
if( !event.detail || (event.detail.type !== this.props.cqType)){
return;
}

Object.assign(this.props, event.detail.data);

this.forceUpdate();
}).bind(this));
}

get imageHTML() {
const imgStyles = {
"display": 'block',
"margin-left": 'auto',
"margin-right": 'auto'
};

return (
<div>
<Link to={this.props.imageLink}>
<img src={this.props.fileReference} style={imgStyles}/>
</Link>
</div>
);
}

render() {
return this.imageHTML;
}
}

export default MapTo('eaem-sites-spa-how-to-react/components/image')(Image,ImageEditConfig);

Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>