Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

How to insert image icon in richtext editor in touch ui?

Level 4
Level 4

Hi all,

I create an custom richtext components in my apps.So, I create an clientlib-media in my component with the categories rte.coralui2 for image icon. It work fine. However, It effected to other apps, that using the richtext editior because my custom richtext component using the categories name rte.coralui2. When i rename the categories name to other name the function doesn't work.

How to use it with do it with other categories name to avoid effect to other apps?


Thanks you so much!


8 Replies
Level 1
Level 1

You could try to add an embedded dependency in your new client lib category.

that would mean your lib (rte.coralui2) would also ship the regular one (rte.coralui)

Using Client-Side Libraries

Level 4
Level 4

When i change to the rte.coralui the icon not display.

Level 10
Level 10

They replied:

it should not affect other RTEs if coded right (since the plugin needs to be enabled for it to work in any RTE)

extraClientLibs is also worth considering (instead of rte.coralui2) for loading the clientlib in any specific component

Level 4
Level 4

I renamed the categories to rte.coralui2_richtext . How to call that categories in edit mode. I try but it dosen't work.


Thank you so much!


Community Advisor
Community Advisor


As Scott says, try to add extraClientLibs property in cq:dialog node.


Level 4
Level 4

Did you mean as below?


The clientlib-media with categories rte.coralui2_richtext

I added extraClientLibs(String[])=rte.coralui2_richtext in cq:dialog

The experrience-aem node is image note, which display icon in rte.

I am tried it but it doesn't work.

This is image-insert.js

(function ($, $document, Handlebars) {

    var ExperienceAEM = {

        GROUP: "experience-aem",

        TIM_FEATURE: "touchuiinsertimage",

        TIM_DIALOG: "touchuiinsertimagedialog",

        CONTENT_URL: "/apps/capitaland/components/content/richtext/popover.html",

        EAEM_RTE_IFRAME_CONTENT: "eaem-rte-iframe-content"


    ExperienceAEM.TIM_UI_SETTING = ExperienceAEM.GROUP + "#" + ExperienceAEM.TIM_FEATURE;

    //extend toolbar builder to register insert image

    ExperienceAEM.CuiToolbarBuilder = new Class({

        toString: "EAEMCuiToolbarBuilder",

        extend: CUI.rte.ui.cui.CuiToolbarBuilder,

        _getUISettings: function (options) {

            var uiSettings = this.superClass._getUISettings(options);

            //inline toolbar

            var toolbar = uiSettings["inline"]["toolbar"],

                feature = ExperienceAEM.TIM_UI_SETTING;

            //uncomment this to make image insert available for inline toolbar

            /*if (toolbar.indexOf(feature) == -1) {

                var index = toolbar.indexOf("fullscreen#start");

                toolbar.splice(index, 0, feature);

                toolbar.splice(index + 1, 0, "-");


            //add image insert to fullscreen toolbar

            toolbar = uiSettings["fullscreen"]["toolbar"];

            if (toolbar.indexOf(feature) == -1) {

                toolbar.splice(3, 0, feature);


            if (!this._getClassesForCommand(feature)) {

                this.registerAdditionalClasses(feature, "coral-Icon coral-Icon--image");


            return uiSettings;



    //popover dialog thats hosts iframe

    ExperienceAEM.InsertImageDialog = new Class({

        extend: CUI.rte.ui.cui.AbstractBaseDialog,

        toString: "EAEMInsertImageDialog",

        getDataType: function () {

            return ExperienceAEM.TIM_DIALOG;



    //extend the CUI dialog manager to register popover dialog

    ExperienceAEM.DialogManager = new Class({

        toString: "EAEMDialogManager",

        extend: CUI.rte.ui.cui.CuiDialogManager,

        create: function (dialogId, config) {

            if (dialogId !== ExperienceAEM.TIM_DIALOG) {

                return, dialogId, config);


            var context = this.editorKernel.getEditContext();

            var $container = CUI.rte.UIUtils.getUIContainer($(context.root));

            var dialog = new ExperienceAEM.InsertImageDialog();

            dialog.attach(config, $container, this.editorKernel, true);

            return dialog;



    //extend the toolkit implementation for returning custom toolbar builder and dialog manager

    ExperienceAEM.ToolkitImpl = new Class({

        toString: "EAEMToolkitImpl",

        extend: CUI.rte.ui.cui.ToolkitImpl,

        createToolbarBuilder: function () {

            return new ExperienceAEM.CuiToolbarBuilder();


        createDialogManager: function (editorKernel) {

            return new ExperienceAEM.DialogManager(editorKernel);



    CUI.rte.ui.ToolkitRegistry.register("cui", ExperienceAEM.ToolkitImpl);

    ExperienceAEM.TouchUIInsertImagePlugin = new Class({

        toString: "TouchUIInsertImagePlugin",

        extend: CUI.rte.plugins.Plugin,

        pickerUI: null,

        getFeatures: function () {

            return [ ExperienceAEM.TIM_FEATURE ];


        initializeUI: function (tbGenerator) {

            var plg = CUI.rte.plugins;

            if (this.isFeatureEnabled(ExperienceAEM.TIM_FEATURE)) {

                this.pickerUI = tbGenerator.createElement(ExperienceAEM.TIM_FEATURE, this, true, "Insert Image");

                tbGenerator.addElement(ExperienceAEM.GROUP, plg.Plugin.SORT_FORMAT, this.pickerUI, 120);



        execute: function (id) {

            var ek = this.editorKernel,

                dm = ek.getDialogManager();

            var dialogConfig = {

                parameters: {

                    "command": ExperienceAEM.TIM_UI_SETTING



            var dialog = this.dialog = dm.create(ExperienceAEM.TIM_DIALOG, dialogConfig);



            var $popover = this.dialog.$dialog.find(".coral-Popover-content");


            function loadPopoverUI($popover) {

                $popover.parent().css("width", ".1px").height(".1px").css("border", "none");

                $popover.css("width", ".1px").height(".1px");

                $popover.find("iframe").attr("src", ExperienceAEM.CONTENT_URL);

                //receive the dialog values from child window



            function receiveMessage(event) {

                if (_.isEmpty( {



                var message = JSON.parse(;

                if(!message || message.sender != ExperienceAEM.EAEM_RTE_IFRAME_CONTENT){



                var action = message.action;

                if(action == "submit"){

                    var data =;

                    if(!_.isEmpty(data) && !_.isEmpty(data.imagePath)){







            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);




        //to mark the icon selected/deselected

        updateState: function (selDef) {

            var hasUC = this.editorKernel.queryState(ExperienceAEM.TIM_FEATURE, selDef);

            if (this.pickerUI != null) {





    CUI.rte.plugins.PluginRegistry.register(ExperienceAEM.GROUP, ExperienceAEM.TouchUIInsertImagePlugin);

    ExperienceAEM.InsertImageCmd = new Class({

        toString: "InsertImageCmd",

        extend: CUI.rte.commands.Command,

        isCommand: function (cmdStr) {

            return (cmdStr.toLowerCase() == ExperienceAEM.TIM_FEATURE);


        getProcessingOptions: function () {

            var cmd = CUI.rte.commands.Command;

            return cmd.PO_BOOKMARK | cmd.PO_SELECTION;


        execute: function (execDef) {

            var data = execDef.value, path = data.imagePath, alt = data.altText || "",

                imageUrl = CUI.rte.Utils.processUrl(path, CUI.rte.Utils.URL_IMAGE),

                imgHtml = "";

            imgHtml += "<img src=\"" + imageUrl + "\" alt=\"" + alt + "\"";

            imgHtml += " " + CUI.rte.Common.SRC_ATTRIB + "=\"" + path + "\"";

            imgHtml += ">";

            execDef.editContext.doc.execCommand("insertHTML", false, imgHtml);



    CUI.rte.commands.CommandRegistry.register(ExperienceAEM.GROUP, ExperienceAEM.InsertImageCmd);

    //returns the picker dialog html

    //Handlebars doesn't do anything useful here, but the framework expects a template

    function cpTemplate() {

        CUI.rte.Templates["dlg-" + ExperienceAEM.TIM_DIALOG] =

            Handlebars.compile('<div data-rte-dialog="' + ExperienceAEM.TIM_DIALOG

                + '" class="coral--dark coral-Popover coral-RichText-dialog">'

                + '<iframe width="1100px" height="700px"></iframe>'

                + '</div>');



})(jQuery, jQuery(document), Handlebars);

Please help me,

Thanks you so much!


Level 10
Level 10

Our touch ui expert replied:

Hey Scott – as per the documentation, extraCLientLibs need to be set in a dialog of that component not plugin