Search code examples
javascriptckeditor5

How to catch an external event from CKEditor 5?


I'm following this guide for write a custom plugin to CKEditor 5. I have actually created a class called InsertImage which extends the Plugin class. Then, I have associated InsertImage to the editor toolbar and the supported plugin and it's working fine.

The problem's that I have to open a modal which contains a list of images inside a list, so far I did this:

import Plugin from '@ckeditor/ckeditor5-core/src/plugin'
import Image from '@ckeditor/ckeditor5-image/src/image';
import imageIcon from '@ckeditor/ckeditor5-core/theme/icons/image.svg';
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';

class InsertImage extends Plugin {
    init() {
        const editor = this.editor;

        editor.ui.componentFactory.add( 'insertImage', locale => {
            const view = new ButtonView( locale );

            view.set( {
                label: 'Insert image',
                icon: imageIcon,
                tooltip: true
            } );

            // Callback executed once the image is clicked.
            view.on( 'execute', () => {
                
                // open the modal which contains a list of image
                $('#modal-media-browse').modal('show');
                
            } );

            return view;
        } );
    }
}

when I click on the image button of the editor, the modal is opened correctly but I don't understand how can I pass the image url from the custom modal. Essentially, after that I've selected the image from the modal (it's a simple list), I have a button that allow me to get the attribute of the image like src, id etc...

how can I pass this custom attributes to the editor?

The example showned in the tutorial of CKEditor describe how to get the content inserted in:

const imageUrl = prompt( 'Image URL' );

and then we have:

editor.model.change( writer => {
    const imageElement = writer.createElement( 'image', {
        src: imageUrl
    } );


    // Insert the image in the current selection location.
    editor.model.insertContent( imageElement, editor.model.document.selection );
} );

but how can I applicate the same logic in an external script? I suppose I should fire an event which the editor must catch and get the src of the image dispatched by that event.

Could someone please tell me how can I pass the image url from an external script to the editor?


Solution

  • My solution to the problem:

    class InsertImage extends Plugin {
        init() {
            const editor = this.editor;
    
            editor.ui.componentFactory.add( 'insertImage', locale => {
                const view = new ButtonView( locale );
    
                view.set( {
                    label: 'Insert image',
                    icon: imageIcon,
                    tooltip: true
                } );
    
                // Callback executed once the image is clicked.
                view.on( 'execute', () => {
                    
                    // apre la modal per la selezione del media
                    $('#modal-media-browse').modal('show');
    
                    $('#modal-media-browse').on('hidden.bs.modal', function() {
                        
                        editor.model.change(writer => {
                            const imageElement = writer.createElement('image', {
                                src: $(this).attr('data-src')
                            });
                            editor.model.insertContent(imageElement, editor.model.document.selection);
                        })
                    });
                } );
    
                return view;
            } );
        }
    }
    

    I store the image src attribute on the modal, so when the modal is closed the event is fired internally of the plugin and the image is added to the editor.