CkEditor5 change event in LiveView

Hello,
I am trying to integrate ckeditor5 in liveview.
I have successfully created the mounted & updated hooks, I now see the ckeditor just fine in my LiveView. But I don"t know how to retrieve the editor content in order to save it.

Running code in app.js:

function ckeditor_fct(it) {
    editor = ClassicEditor
        .create(it.el)

        .catch(error => {
            console.error(error);
        })
}

let Hooks = {}
Hooks.CkEditor = {
    mounted() {
        console.log("mount");
        ckeditor_fct(this)
    },
    beforeUpdate() {
        console.log("beforeUpdate");
    },
    disconnected() {
        console.log("disconnected");
    },
    reconnected() {
        console.log("reconnected");
    },
    destroyed() {
        console.log("destroyed");
    },
    updated() {
        console.log("updated");
        ckeditor_fct(this)
    }
}
let liveSocket = new LiveSocket("/live", Socket, { hooks: Hooks, params: { _csrf_token: csrfToken } })

I have tried to add this code to ckeditor_fct function

editor.model.document.on( 'change:data', () => {
    console.log( 'The data has changed!' );
} );

but this code crashes at execution :

app.js:44 Uncaught TypeError: Cannot read properties of undefined (reading ‘document’)

I have tried

    it.el.addEventListener('change', () => {
        console.log('The data has changed!');
    });

No crash, but no event received.

I admit that I’m bad with JavaScript.
As It is, user modification does not even survive any change made in the other form fields : content of the CKeditor is lost upon any updated event received.
I have seen in https://elixirforum.com/t/ckeditor5-in-liveview/44122 a recommendation to

restore state on updated (copied from beforeUpdate).

but I don’t know how to do that.
Also, in order to save the editor content, I believe I need to receive the change event.

I spent 8 hours trying to fix this, but I’m stuck.

Thank you for your help :slight_smile:

1 Like

Found a way that works !

function ckeditor_fct(it) {

    editor = ClassicEditor
        .create(it.el)
        .then(editor => {
            editor.model.document.on('change:data', (evt, data) => {
                console.log(editor.getData());
            });
        })
        .catch(error => {
            console.error(error);
        })
}
5 Likes

Thanks for posting a solution!