Search code examples
javascriptvue.jsckeditorckeditor4.x

Plugins don't work with multiple instances of CKEditor4 in Vue Components


I have created a Vue component for rich text editing using CKEditor 4 for my website. When this component is mounted for the first time, the editor and all the default plugins work fine but when another instance of the same component is mounted dynamically on the same page, the plugins such as Table, Image etc. which involve a popup dialog do not work (I am unable to type in any of the text inputs in the dialogs, such as Table Columns and Rows). The same issue exists with the official ckeditor4-vue package as well. I tried to resolve the issue by using the general package (zip) instead of the vue specific one but that didn't help. Here is my code.

<template>
    <div>
        <textarea v-bind:id="fieldName" v-bind:name="fieldName" v-model="content"></textarea>
    </div>
</template>

<script>
    import './config';
    import './ckeditor/ckeditor';
    export default {
        props: {
            currentContent: {
                type: String,
                default: null,
            },
            fieldName: {
                type: String,
                default: 'content',
            },
            toolbarType: {
                type: String,
                default: 'Full',
            },
        },
        data: function () {
            return {
                editorConfig: {
                    toolbar_Full: null,
                    toolbar: this.toolbarType,
                },
                editor: null,
                content: null,
                initialized: false,
                siteUrl: siteUrl,
            };
        },
        mounted: function () {
            let vm = this;
            vm.initializeTextarea();
        },
        beforeDestroy: function () {
            let vm = this;
            vm.destroyTextarea();
        },
        methods: {
            initializeTextarea: function () {
                let vm = this;
                var editorConfig = JSON.parse(JSON.stringify(vm.editorConfig));
                vm.editor = CKEDITOR.replace(vm.fieldName, editorConfig);
                console.log("After Initialize: CKEditor Instances: ",CKEDITOR.instances);
            },
            destroyTextarea: function () {
                let vm = this;
                CKEDITOR.instances[vm.fieldName].destroy();
                console.log("After Destroy: CKEditor Instances: ",CKEDITOR.instances);
            },
        },
    };
</script>

To replicate the issue, the component can be imported into another component and a second instance of the same component can be added dynamically using v-if, the plugins mentioned above would not work correctly in the second (dynamically created) instance.

EDIT I tried changing the v-if to a v-show to check if it works if both are initialized simultaneously but that didn't help either. Even if both editor instances are present on a simple HTML page, the plugins don't work.


Solution

  • It turned out to be a jQuery dialog interfering with CKEditor's dialog. Once the editor was placed outside the dialog, the plugins work as long as no other jQuery dialog is open on the same window/tab.