AEM 62 - Touch UI Rich Text Editor InPlace Editing perform Spell Check before Save

Goal


Touch UI Rich Text Editor In Place Editing - perform Spell Check on the edited content before saving it to CRX.

Out of the box spell check plugin is available in InPlace editing full screen mode (enable the plugin in rtePlugins eg. /libs/foundation/components/text/dialog/items/tab1/items/text/rtePlugins/spellcheck); With the plugin enabled, user has to explicitly click on the following plugin button before saving, to do the spell check on content...



This extension listens to the beforeFinish event of InPlace Editing to do the spellcheck, relieving user from the manual task of clicking spellcheck button each time; provides spell check functionality in inline mode as well

Spellcheck DOESN'T need to be enabled (in rtePlugins) for this extension to work

Demo | Package Install




Solution


1) Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/eaem-touchui-rte-spellcheck-before-save

2) Create node /apps/eaem-touchui-rte-spellcheck-before-save/clientlib of type cq:ClientLibraryFolder and add a String property categories with value cq.authoring.dialog and dependencies to underscore

3) Create file (nt:file) /apps/eaem-touchui-rte-spellcheck-before-save/clientlib/js.txt and add

                       inline-edit-spellcheck-before-save.js

4) Create file (nt:file) /apps/eaem-touchui-rte-spellcheck-before-save/clientlib/inline-edit-spellcheck-before-save.js and add the following code

(function ($, $document, gAuthor) {
    if(!gAuthor){
        return;
    }

    var SPELL_CHECK_URL = "/libs/cq/ui/rte/spellcheck",
        currentEditable = null, doSpellCheck = true;

    $document.on("cq-editables-loaded", function(event){
        $.each(event.editables, function(index, editable){
            if(!editable.dom || !isInPlaceEditingEnabled(editable)){
                return;
            }

            editable.dom.on("editing-start", getEditStartedListener(editable));
        });
    });

    $document.on("inline-edit-finish", function (event) {
        event.editable.dom.on("editing-start", getEditStartedListener(event.editable));
    });

    function isInPlaceEditingEnabled(editable){
        try{
            var editConfig = editable.config.editConfig;
            return editConfig && editConfig.inplaceEditingConfig && editConfig.inplaceEditingConfig.active;
        }catch(err){
            return false;
        }
    }

    function getEditStartedListener(editable){
        var gRegistry = Granite.author.editor.registry,
            emptyFn = function(){};

        if(_.isEmpty(gRegistry)){
            console.log("EAEM - Granite author registry not available");
            return emptyFn;
        }

        var inlineTextEditor = gRegistry["text"];

        if(!inlineTextEditor){
            console.log("EAEM - Granite author rte not available");
            return emptyFn;
        }

        return function eaemEditStartedListener(){
            if(!inlineTextEditor.rte){
                return;
            }

            currentEditable = editable;

            doSpellCheck = true;

            var listeners = inlineTextEditor.rte.options.listeners,
                beforeFinishFn = listeners["beforeFinish"],
                onStartedFn = listeners["onStarted"];

            if(!beforeFinishFn){
                listeners["beforeFinish"] = eaemBeforeFinishListener;
            }else{
                listeners["beforeFinish"] = function(){
                    eaemBeforeFinishListener();
                    beforeFinishFn();
                }
            }

            if(!onStartedFn){
                listeners["onStarted"] = eaemEditStartedListener;
            }else{
                listeners["onStarted"] = function(){
                    eaemEditStartedListener();
                    onStartedFn();
                }
            }
        }
    }

    function eaemBeforeFinishListener(){
        return performSpellCheck(this.getContent());
    }

    function performSpellCheck(content){
        if(!doSpellCheck){
            return false;
        }

        var doNotSave = false;

        $.ajax({
            async: false,
            url: SPELL_CHECK_URL,
            data: {
                "_charset_": "utf-8",
                "mode": "text",
                "html": "true",
                "text": content
            }
        }).done(handler);

        function handler(spellCheckResults){
            if(_.isEmpty(spellCheckResults.words)){
                return;
            }

            var spellCheckPlugin = getMockSpellCheckPlugin();
            spellCheckPlugin.checkSuccess(spellCheckResults);

            showMessageBox("Spell check found mistakes...", "Spellcheck");

            doNotSave = true;
        }

        return doNotSave;
    }

    function getMockSpellCheckPlugin(){
        var inlineTextEditor = Granite.author.editor.registry["text"],
            spellCheckPlugin = new CUI.rte.plugins.SpellCheckerPlugin(inlineTextEditor.rte.editorKernel, "spellcheck");

        spellCheckPlugin.config = {
            "invalidStyle": "border-bottom: dotted red;"
        };

        spellCheckPlugin.checkTextUI = {
            setHighlighted: function(){}
        };

        return spellCheckPlugin;
    }

    function showMessageBox(message, title){
        var fui = $(window).adaptTo("foundation-ui"),
            options = [{
                id: "RE-EDIT",
                text: "RE-EDIT",
                primary: true
            },{
                id: "SAVE",
                text: "SAVE",
                warning: true
            }];

        message = message || "Message";
        title = title || "Title";

        fui.prompt(title, message, "error", options, handler);

        function handler(btnId){
            var inlineTextEditor = Granite.author.editor.registry["text"];

            doSpellCheck = false;

            if (btnId === "SAVE") {
                inlineTextEditor.rte.editorKernel.execCmd("save");
            }else{
                _.debounce(startInlineEdit, 500)();
            }
        }
    }

    function startInlineEdit(){
        var inlineTextEditor = Granite.author.editor.registry["text"];
        inlineTextEditor.startInlineEdit(currentEditable);
    }
}(jQuery, jQuery(document), Granite.author));

4 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Hi Sreekanth,

    thank you for the great post. one follow up question, I have. we are using the inline-edit-finish event, if there is an error on spell check.. I have 2 options reedit and save.. By that point of time, already the text is saved in the jcr... now we are prompting the dialog to modify the spelling accordingly with reedit. At this point of time, If I reload the browser, since the text is already present in jcr, now the text with incorrect spelling loads up.. it only corrects next time when I edit the rte component.

    Rather than inline-edit-finish, can we rely on any other event, before storing the actual content in the jcr. Please suggest.

    ReplyDelete
  3. A great information about Rich text editor JavaScript you have shared keep it up.

    ReplyDelete
  4. Nice blog with Amazing information .. love to read about this.
    Awaiting for your new post
    We at Fullassignment.com bring to you the most significant Management assignment help writing service at the best cost. With long stretches of understanding we are prepared to give online assignment help over the globe.You will be guided here with a portion of the information of Management assignment which could assist you in deciding writing a Manageent assignment. Nonetheless, we unequivocally prescribe you to benefit Leadership Assignment help from our specialist to find out about marketing and its scope.We also provide Macro Economics Assignment Help from our experts.

    https://fullassignment.com/

    ReplyDelete