'CKEditor 5 – get editor instances

I am migrating from CKEditor 4.7 to 5.

In CKE4, I would do something like this: CKEDITOR.replace('text_area'); and then in another JS function I could get the data by CKEDITOR.instances.text_area.getData().

But it doesn't appear that CKE5 has a function ClassicEditor.instances or something analogous.

I know I can store the editor instance as a global JS variable, but the code I am working with creates the editors in a general function, so I can't just create a global variable since I don't know the name of the editor a priori. There can also be several editors active on the screen at the same time.

Is there no analog in CKE5 to the old instances that would allow me to get an editor instance from just the id of the textarea it replaced?

I guess I could create my own global array to hold the editor instances, but I would rather not if there is something built in and better-supported



Solution 1:[1]

This question was already answered in How to get data from CKEDITOR5 instance, but let's consider here a case with more than one editor instance.

I guess I could create my own global array to hold the editor instances, but I would rather not if there is something built in and better-supported

There's no repository of editor instances. We could add it but we don't feel that this is an essential feature. It's actually something that people got used to in CKEditor 4 so they never thought and learned how to manage their editors by themselves.

Also, the reason why there's no single repository of instances is that there's no central singleton object at all. You may implement multiple editor classes and they don't have to know about each other. To come up with a repository, we'd need to centralise these things again.

So, as you pointed out yourself, a simple way to store all instances would be by having a global (global within your app or module, not necessarily a "global JS variable") map of these instances.

The keys to these instances can be the ids of elements on which you initialised editors:

const editors = {}; // You can also use new Map() if you use ES6.

function createEditor( elementId ) {
    return ClassicEditor
        .create( document.getElementById( elementId ) )
        .then( editor => {
            editors[ elementId ] = editor;
        } )
        .catch( err => console.error( err.stack ) );
}

// In real life, you may also need to take care of the returned promises.
createEditor( 'editor1' );
createEditor( 'editor2' );

// Later on:
editors.editor1.getData();

What if you don't assign ids to elements in the DOM? If you use ES6, then it's not a problem. Elements, like other objects, can be keys of a map.

const editors = new Map();

function createEditor( elementToReplace ) {
    return ClassicEditor
        .create( elementToReplace )
        .then( editor => {
            editors.set( elementToReplace, editor );
        } )
        .catch( err => console.error( err.stack ) );
}

// In real life, you may also need to take care of the returned promises.
createEditor( textarea1 );
createEditor( textarea2 );

// Later on:
editors.get( textarea1 ).getData();

If you can't use ES6, then you'd need to do a bit more – e.g. dynamically assign some data-editor-id attributes to elements on which you create the editors.

Solution 2:[2]

It's not the first time I'm trying to remind myself how to access the CKEditor instance on a production website having just access to the DOM via the developer console, so a reminder for myself ;)

https://ckeditor.com/docs/ckeditor5/latest/builds/guides/faq.html#how-to-get-the-editor-instance-object-from-the-dom-element

It's possible to access the editor instance using the ckeditorInstance property which is available on the contenteditable element that CKEditor 5 is using. You can access this DOM element via e.g. the .ck-editor__editable class.

// A reference to the editor editable element in the DOM.
const domEditableElement = document.querySelector( '.ck-editor__editable' );
    
// Get the editor instance from the editable element.
const editorInstance = domEditableElement.ckeditorInstance;
    
// Now you can use the editor instance API.
editorInstance.setData( '<p>Hello world!<p>' );

Solution 3:[3]

Running multiple copies of the editor using jQuery and a class selector:

$( '.editor' ).each( function() {
    InlineEditor
        .create( this )
        .catch( error => {
            console.error( error );
        } );
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Reinmar
Solution 2
Solution 3 wp-mario.ru