Ckeditor5: Insert Image

Created on 8 Sep 2017  Â·  29Comments  Â·  Source: ckeditor/ckeditor5

I'm using Summernote as my editor. It works well. But recently I have a new project which need to save document as Markdown file.
CKEditor 5 looks promising and can save document as Markdown file.

In Summernote, I can use onImageUpload() callback function trigger my loadImage() function, get the URL and using $('#instruction').summernote('insertImage', imgURL) insert the image.

How can I insert image in CKEditor 5?

Thanks,
Andrew

docs

Most helpful comment

@zulfi-mod

Even if @Reinmar last answer is correct, i'll search this like you and found it

the response look like this:

{
  "uploaded": "true/false",
  "url": "path/to/the/file.ext"
}

you can see it here

All 29 comments

Hi Andrew,

One question – do you want to insert an image of which you know URL already? Like:

editor.execute( 'insertImage', 'https://url/to/the/image' );

Which would result in inserting <img> like this:

<img src="https://url/to/the/image">

I'm asking because you mentioned uploading so I also thought that perhaps you would like to upload an image of which you have an URL or of which you have a source (e.g. as a File object).

Can I insert image using these two methods:

  1. Just insert the image using a link(which I already uploaded the image to the server and got the link), and the image shows out in the document.

  2. Select the image file(using input type='file', or better drap & drop), click upload, it will upload the image to a server URL(can be configured), and the server will return the image URL to CKEditor, then the editor insert the image link and shows the image.

Thanks for your response.
Andrew

1) Inserting via URL

Surprisingly, we don't have a specific command for this action because none of the existing features needed it already. However, this is pretty simple:

import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';

function insertImage( editor, imageUrl, imageAlt ) {
    const doc = editor.document;

    doc.enqueueChanges( () => {
        const imageElement = new ModelElement( 'image', {
            src: imageUrl, 
            alt: imageAlt
        } );

        editor.data.insertContent( imageElement, doc.selection );
    } );
}

Executing insertImage() should result in inserting the image at the selection position. The undo integration, selecting the image and everything is already handled.

In the future, we may create a command which does this.

2) Inserting via file

Here, we already have a command and even an adapter for CKFinder. We also have the "File button" UI component which opens a "browser file" window and lets you choose an image from your disk.

Those features are implemented in these plugins:

  • ImageUploadEngine – introduces imageUpload command. You can see here what arguments it accept: ImageUploadCommang#execute(). Example:

    editor.execute( 'imageUpload', { file: file } );
    
  • However, the upload feature needs an adapter which will handle sending the file to the server. We implemented CKFinderUploadAdapter plugin (you can see its code here) which handles sending files to CKFinder backend. You can use it or implement your own adapter.

  • Finally, if you want the button you need to load the ImageUpload plugin and configure the toolbar to contain 'insertImage' item.

Note: These plugins are not yet included in the builds so you'll need to customise one or simply integrate the editor directly into your app.

BTW, enabling the ImageUploadEngine plugin enables also support for pasting and dropping images directly into the editor :)

We don't have a live demo of this yet, but this is a screencast from one of our manual tests:

sep-13-2017 10-04-13

This is its code:

https://github.com/ckeditor/ckeditor5-adapter-ckfinder/blob/master/tests/manual/uploadadapter.js

That's what I want. I appreciate your quick response and the solution(screen cast).

Thank you very much.

Andrew

I'd actually keep this open because I'd like if there was some documentation for that.

Hello @Reinmar,

I am also interested by inserting an image node at the current position (with an inline editor).
I tried to use the following code:

import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element';

function insertImage( editor, imageUrl, imageAlt ) {
    const doc = editor.document;

    doc.enqueueChanges( () => {
        const imageElement = new ModelElement( 'image', {
            src: imageUrl, 
            alt: imageAlt
        } );

        editor.data.insertContent( imageElement, doc.selection );
    } );
}

But I get the error model-position-before-root.
Unfortunately, I didn't find more information in the documentation and in the issue tracker to accomplish the insertion.
Is there an existing method to do this? I only found setData(data) and getData() to interact with the content of the editor.

I would be very grateful if somebody can help me!
Thanks.

The code you posted is correct. Or at least it seems so at the first glance. You used the correct method. Actually, I tested this code when writing the Quick start guide and it worked (as proved by screenshots). But I remember that I had a similar error at some point when writing that guide and I had some simple issue in my code... ;|

Could you post a stack trace? And how are you loading this feature into the editor? Because if you try to use a CKEditor 5 build then it might not work because of that.

Because if you try to use a CKEditor 5 build then it might not work because of that.

What I meant is that if you use an already precompiled code (e.g. one of the builds) and then import Element from @ckeditor/ckeditor5-engine, then that module and all modules on which it depends are duplicated and there's a conflict somewhere deep there.

This is inconvenient and, as I reported in https://github.com/ckeditor/ckeditor5-engine/issues/858#issuecomment-336994447, we'll work on improving this situation.

InsertImage feature is in development mode? Why bcz I am using https://cdn.ckeditor.com/ckeditor5/1.0.0-alpha.1/inline/ckeditor.js ckeditor5 build plugin, Insert image feature not working in the latest CKEDitor5.Please refer the jsfiddle examples by using inline editor https://jsfiddle.net/vrVAP/3722/
Is there any support to require JS?

I extended my answer for https://stackoverflow.com/questions/46765197/how-to-enable-image-upload-support-in-ckeditor-5 to contain code snippets. Please read it because it clarifies what you need to do to enable image upload in the builds (which can be done by just configuring the editor).

And Require.JS has nothing to do with image upload and isn't needed here at all. You just need to configure one of the existing (and included in all builds) upload adapters or write your own adapter.

I am using require JS plugin to config the JS files in my project. How to config CKEditor5 in the requireJS?

I'm sorry, but I have no idea what you mean and what problem you have.

I mean how to call CKEditor5 plugin by using requireJS? And also How to add Underline,code etc.. icons into CKEditor5?
Application JSON Response it will come below like this once upload the file to server.When I saw the plugin response type is JSON and append as 'upload' to formdata.How to customize? Why bcz it's throughing can not upload file.
{
id:'uploadId',
caption:'filename'
...........
}
Can you please help?

Hi @Reinmar,

Sorry for my late reply and thank you for great explanation and link!
Exactly. I used a precompiled code so there was a conflict as you said.
If it can help someone:

Wrong import:

import InlineEditor from '@ckeditor/ckeditor5-build-inline'
import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element'

Correct import:

import InlineEditor from '@ckeditor/ckeditor5-editor-inline/src/inlineeditor'
import ModelElement from '@ckeditor/ckeditor5-engine/src/model/element'

Hi @Reinmar
Once upload the file from front end to server what response will except inlineeditor plugin.
I am uploading the file by using file browser,it's uploaded successfully and send response as 'application/json' format like below
{
id:'uploadId',
caption:'filename'
...........
}
But front end it's showing cannot upload the file. Can you please help me?

@Reinmar
I am trying to upload images using the CKFinder upload adapter but with my own service to upload images to the server.

InlineEditor
         .create( document.querySelector( '#imageEditor1'),{
             toolbar: ['undo','redo'],
             ckfinder: {
                 uploadUrl: '${pageContext.request.contextPath}/uploadImage.html?command=QuickUpload&type=Files&responseType=json
             }
         })
         .catch( error => {
             console.error( error );
         } );

I am returning a json of the format as shown below. But the upload adapter always alerts with message "Cannot upload file : dubai.jpg"

Response in json format from my service:

{url: "http://localhost:8080/contentserver/destination-deals/img/M000002/default/en/dubai.jpg"}

When I debug, I am getting the instance "this" as undefined and subsequently the reference to the XMLHttpRequest object "xhr" also is undefined.

Please help me and tell me If I am doing this the wrong way. Do I have to code a new adapter altogether?

Thank You.

Regards,
Zulfiqar

The source of the CKFinder upload adpater is here: https://github.com/ckeditor/ckeditor5-adapter-ckfinder/blob/master/src/uploadadapter.js. Maybe it will help you tracking the issue because it's hard for me to guess what might've gone wrong.

Thank you for the quick reply. Can you tell me whether I have used the built in ck finder upload adapter in the proper way? Whether I am returning a proper response?

It has just one configuration option – the URL to which the file is uploaded. So if you've set that, then yes.

Hi! This is an issue tracker. Unless you're able to prove that there's an issue, a correct place to ask questions like this would be https://stackoverflow.com/questions/tagged/ckeditor5. However, you're asking to debug your specific integration, so I don't think that anyone will be able to help you there anyway.

@zulfi-mod

Even if @Reinmar last answer is correct, i'll search this like you and found it

the response look like this:

{
  "uploaded": "true/false",
  "url": "path/to/the/file.ext"
}

you can see it here

Here is example, how to implement it into Laravel controller with http://laravel-mediable.readthedocs.io/en/latest/uploader.html uploader

/**
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse
 */
public function upload(Request $request)
{
    try {
        $file = $request->file('upload');

        $uploader = \MediaUploader::fromSource($file);
        $uploader->setAllowedMimeTypes(['image/jpeg', 'image/gif', 'image/png']);
        $uploader->setAllowedExtensions(['jpg', 'jpeg', 'png', 'gif']);
        $media = $uploader->upload();

        return response()->json([
            'uploaded' => true,
            'url' => $media->getUrl()
        ]);
    } catch (\Exception $e) {
        return response()->json(
            [
                'uploaded' => false,
                'error' => [
                    'message' => $e->getMessage()
                ]
            ]
        );
    }
}

@Reinmar Hi,I'm using the 4.10 standard version, uploading pictures to the server is successful, but the browser can't return the image's server address: http://xxx.com/image.jpg. The server returned JSON data successfully, {url, uploaded, fileName}, I just configured config.imageUploadUrl in config.js. I don't know what else to configure.

thanks a lot

This is CKEditor 5's issue tracker. You're asking about CKEditor 4 which has its issues tracked on http://github.com/ckeditor/ckeditor-dev. But what you describe isn't an editor bug or a feature request, so Stack Overflow will be a more fitting place.

Hi,
Can anyone give the code available in core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json

@rushi02 CKFinder is commercial software and we cannot share the source code of the server connector with you, sorry.

Was this page helpful?
0 / 5 - 0 ratings