AEM 62 - Touch UI Extend RTE List Plugin for adding selected CSS class

Goal


In Touch UI RTE (Rich Text Editor) extend the List plugin to apply user selected css class

Demo | Package Install | GitHub






Solution


1) Login to CRXDE Lite, create folder (nt:folder) /apps/eaem-touch-rte-list-plugin-css

2) Create dialog /apps/eaem-touch-rte-list-plugin-css/dialog/cq:dialog with the allowed css classes for user selection (applied on list)

<?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" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Css Class"
    sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/container">
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
            margin="{Boolean}false"/>
        <items jcr:primaryType="nt:unstructured">
            <column
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <css-classes
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/foundation/form/select"
                        emptyText="Select css class..."
                        name="./cssClass">
                        <items jcr:primaryType="nt:unstructured">
                            <red
                                jcr:primaryType="nt:unstructured"
                                text="coral-Tag--red"/>
                            <magenta
                                jcr:primaryType="nt:unstructured"
                                text="coral-Tag--magenta"/>
                            <fuchsia
                                jcr:primaryType="nt:unstructured"
                                text="coral-Tag--fuchsia"/>
                            <plum
                                jcr:primaryType="nt:unstructured"
                                text="coral-Tag--plum"/>
                            <blue
                                jcr:primaryType="nt:unstructured"
                                text="coral-Tag--blue"/>
                        </items>
                        <select
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/foundation/button"
                            class="coral-Button--primary"
                            text="Select"/>
                    </css-classes>
                </items>
            </column>
        </items>
    </content>
</jcr:root>

3) Create clientlib (type cq:ClientLibraryFolder/apps/eaem-touch-rte-list-plugin-css/clientlib and set property categories of String[] type to cq.authoring.dialog and dependencies to underscore

4) Create file ( type nt:file ) /apps/eaem-touch-rte-list-plugin-css/clientlib/js.txt, add the following

                         list-plugin-css.js

5) Create file ( type nt:file ) /apps/eaem-touch-rte-list-plugin-css/clientlib/list-plugin-css.js, add the following code

(function ($) {
    "use strict";

    var _ = window._,
        Class = window.Class,
        GROUP = "experience-aem",
        CSS_DIALOG = "/apps/eaem-touch-rte-list-plugin-css/dialog/cq:dialog.html",
        CUI = window.CUI;

    var EAEMCSSListCmd = new Class({
        extend: CUI.rte.commands.List,

        toString: "EAEMCSSListCmd",

        execute: function(execDef) {
            this.superClass.execute.call(this, execDef);

            var list = this.getDefiningListDom(execDef.editContext, execDef.nodeList);

            if(!list){
                return;
            }

            registerReceiveDataListener(receiveMessage);

            if(!this.eaemSelectCssDialog){
                this.eaemSelectCssDialog = showDialog();
            }

            var eaemSelectCssDialog = this.eaemSelectCssDialog;

            eaemSelectCssDialog.show();

            function receiveMessage(event) {
                if (_.isEmpty(event.data)) {
                    return;
                }

                var message = JSON.parse(event.data);

                if (!message || message.sender !== GROUP) {
                    return;
                }

                $(list).addClass(message.data.cssClass);

                eaemSelectCssDialog.hide();

                removeReceiveDataListener(receiveMessage);
            }
        }
    });

    function showDialog(){
        var html = "<iframe width='540px' height='250px' frameBorder='0' src='"
                        + CSS_DIALOG + "?requester=" + GROUP + "'>"
                    + "</iframe>";

        var cuiDialog = new Coral.Dialog().set({
            backdrop: 'static',
            header: {
                innerHTML: 'Select css class'
            },
            content: {
                innerHTML: html
            }
        });

        document.body.appendChild(cuiDialog);

        return cuiDialog;
    }

    function removeReceiveDataListener(handler) {
        if (window.removeEventListener) {
            window.removeEventListener("message", handler);
        } else if (window.detachEvent) {
            window.detachEvent("onmessage", handler);
        }
    }

    function registerReceiveDataListener(handler) {
        if (window.addEventListener) {
            window.addEventListener("message", handler, false);
        } else if (window.attachEvent) {
            window.attachEvent("onmessage", handler);
        }
    }

    CUI.rte.commands.CommandRegistry.register("_list", EAEMCSSListCmd);
})(jQuery);

(function($, $document){
    var SENDER = "experience-aem",
        REQUESTER = "requester",
        CSS_CLASS = "cssClass";

    if(queryParameters()[REQUESTER] !== SENDER ){
        return;
    }

    $document.on("foundation-contentloaded", stylePopoverIframe);

    function queryParameters() {
        var result = {}, param,
            params = document.location.search.split(/\?|\&/);

        params.forEach( function(it) {
            if (_.isEmpty(it)) {
                return;
            }

            param = it.split("=");
            result[param[0]] = param[1];
        });

        return result;
    }

    function stylePopoverIframe(){
        var $dialog = $(".cq-dialog").css("background", "white"),
            $selectBut = $dialog.find(".coral-Button--primary");

        $dialog.find(".cq-dialog-header").hide();
        $dialog.find(".cq-dialog-content").css("top", ".1rem");

        $selectBut.css("margin", "120px 0 0 380px").click(sendDataMessage);
    }

    function sendDataMessage(){
        var message = {
            sender: SENDER,
            data: {}
        }, $dialog, cssClass;

        $dialog = $(".cq-dialog");

        cssClass = $dialog.find("[name='./" + CSS_CLASS + "']").val();

        message.data[CSS_CLASS] = cssClass;

        parent.postMessage(JSON.stringify(message), "*");
    }
})(jQuery, jQuery(document));

No comments:

Post a Comment