AEM 64 - Touch UI Extend Rich Text Editor (RTE) to select Anchor for creating Deep Links

Goal


Extend the Link Dialog of Touch UI Rich Text Editor to add a Coral Select widget for showing named anchor links on selected page to create deep links

Demo | Package Install | Github


Drop down with list of Anchors



Anchors on linked page




Solution


1) Login to CRXDE Lite, create folder (nt:folder) /apps/eaem-touchui-extend-rte-select-deep-link


2) Create clientlib (type cq:ClientLibraryFolder) /apps/eaem-touchui-extend-rte-select-deep-link/clientlib and set property categories of String type to cq.authoring.dialog.all and dependencies String[] to lodash


3) Create file ( type nt:file ) /apps/eaem-touchui-extend-rte-select-deep-link/clientlib/js.txt, add the following


                         deep-links.js

4) Create file (type nt:file) /apps/eaem-touchui-extend-rte-select-deep-link/clientlib/deep-links.js, add the following code

(function ($) {
    "use strict";

    var _ = window._,
        Class = window.Class,
        CUI = window.CUI,
        EAEM_ANCHOR_SELECT = "eaem-anchor-select",
        RTE_LINK_DIALOG = "rtelinkdialog";

    if(CUI.rte.ui.cui.CuiDialogHelper.eaemExtended){
        return;
    }

    var EAEMLinkBaseDialog = new Class({
        extend: CUI.rte.ui.cui.CQLinkBaseDialog,

        toString: "EAEMLinkBaseDialog",

        initialize: function(config) {
            this.superClass.initialize.call(this, config);

            var baseDialog = this;

            this.$rteDialog = this.$container.find("[data-rte-dialog=link]");

            var $path = this.$rteDialog.find(".rte-dialog-columnContainer:first");

            $(baseDialog.getAnchorsSelect()).insertAfter($path);

            $path.find("foundation-autocomplete").on("foundation-field-change", constructSelect);

            function constructSelect() {
                var pathField = $(this).adaptTo('foundation-field');

                $.get(pathField.getValue() + ".html?wcmmode=disabled").done(successFn);

                function successFn(respHtml){
                    var $aTags = $(respHtml).find("a"), options = [];

                    $aTags.each(function( i, aTag ) {
                        if(_.isEmpty(aTag.name)){
                            return;
                        }

                        options.push(aTag.name);
                    });

                    $(baseDialog.getAnchorsSelect(options)).insertAfter($path);
                }
            }
        },

        getAnchorsSelect: function(options, dValue){
            $("#" + EAEM_ANCHOR_SELECT).remove();

            var html = '<div class="rte-dialog-columnContainer" id="' + EAEM_ANCHOR_SELECT + '">' +
                            '<div class="rte-dialog-column">' +
                                '<coral-select class="coral-Form-field" placeholder="Select Link">';

            _.each(options, function(option){
                html = html + '<coral-select-item value="' + option + '"'
                            + ( (dValue == option) ? " selected " : "" ) + '>' + option + '</coral-select-item>';
            });

            html = html + '</coral-select></div></div>';

            return html;
        },

        dlgFromModel: function() {
            if (_.isEmpty(this.objToEdit) || _.isEmpty(this.objToEdit.href)
                        || (this.objToEdit.href.indexOf("#") == -1)) {
                this.superClass.dlgFromModel.call(this);
                return;
            }

            var href = this.objToEdit.href, anchor,
                $path = this.$rteDialog.find(".rte-dialog-columnContainer:first");

            this.objToEdit.href = href.substring(0, href.lastIndexOf("#"));

            this.superClass.dlgFromModel.call(this);

            anchor = href.substring(href.lastIndexOf("#") + 1);

            $.get(href + ".html?wcmmode=disabled").done($.proxy(successFn, this));

            function successFn(respHtml){
                var $aTags = $(respHtml).find("a"), options = [];

                $aTags.each(function( i, aTag ) {
                    if(_.isEmpty(aTag.name)){
                        return;
                    }

                    options.push(aTag.name);
                });

                $(this.getAnchorsSelect(options, anchor)).insertAfter($path);
            }
        },

        dlgToModel: function() {
            this.superClass.dlgToModel.call(this);

            var anchorSelect = this.$dialog.find("#" + EAEM_ANCHOR_SELECT + " >* coral-select");

            if(_.isEmpty(anchorSelect)){
                return;
            }

            var aVal = anchorSelect.val();

            if (_.isEmpty(aVal)) {
                return;
            }

            this.objToEdit.href = this.objToEdit.href + "#" + aVal;
        }
    });

    CUI.rte.ui.cui.CuiDialogHelper = new Class({
        extend: CUI.rte.ui.cui.CuiDialogHelper,

        toString: "EAEMCuiDialogHelper",

        instantiateDialog: function(dialogConfig) {
            var type = dialogConfig.type;

            if(type !== RTE_LINK_DIALOG){
                this.superClass.instantiateDialog.call(this, dialogConfig);
                return;
            }

            var $editable = $(this.editorKernel.getEditContext().root),
                $container = CUI.rte.UIUtils.getUIContainer($editable),
                dialog = new EAEMLinkBaseDialog();

            dialog.attach(dialogConfig, $container, this.editorKernel);

            return dialog;
        }
    });

    CUI.rte.ui.cui.CuiDialogHelper.eaemExtended = true;
})(jQuery);

No comments:

Post a Comment