Upload and render image in draft-js based editor
Asked Answered
V

2

5

I am trying to create a simple editor for writing a storyline. Right now I could show the html to markup in the editor where bold text are shown in bold and etc. I could also send the data in html form to server but I could not show the image in an editor and also could not upload the image in editor. I have created a codesandbox of it. Here is the link

https://codesandbox.io/s/5w4rp50qkp

The line of code is a bit huge. That is why I am posting the code in codesandbox where you can see the demo either.

Can anyone please help me to make this possible?

Viper answered 20/9, 2017 at 11:4 Comment(9)
what you have tried?Stanwinn
I have posted in the sandbox.Viper
I mean what you did for showing image in draftjs?Stanwinn
I have used compositeDecorator. Do I have to do much more than this? Can you help me on this, please?Viper
image showing not relate to compositeDecorator. why not check the official image display example.Stanwinn
I did not found it. I am trying this since 3 dayViper
https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/entity/entity.html replace cunstom component with imageStanwinn
I get page not found errorViper
github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/…Stanwinn
H
6

I originally posted my answer here

I copied it below for your convenience:


Took a while to figure out how to insert image after checking Draft.js source code.

  insertImage = (editorState, base64) => {
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
      'image',
      'IMMUTABLE',
      { src: base64 },
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const newEditorState = EditorState.set(
      editorState,
      { currentContent: contentStateWithEntity },
    );
    return AtomicBlockUtils.insertAtomicBlock(newEditorState, entityKey, ' ');
  };

Then you can use

const base64 = 'aValidBase64String';
const newEditorState = this.insertImage(this.state.editorState, base64);
this.setState({ editorState: newEditorState });

For render image, you can use Draft.js image plugin.

Live demo: codesandbox

The demo inserts a Twitter logo image.


If you want to insert a image from local file, you can try to use FileReader API to get that base64.

For how to get base64, it is simple, check

Live demo: jsbin

Now go ahead to put them together, you can upload image from local file!

Hawse answered 3/12, 2017 at 1:19 Comment(0)
C
2

Set uploadEnable to true and call uploadCallBack

<Editor ref='textEditor'
       editorState={this.state.editorState}
       toolbar={{
            options: ['image',],
                        
            image: {
            uploadEnabled: true,
            uploadCallback: this.uploadCallback,
            previewImage: true,
            inputAccept: 'image/gif,image/jpeg,image/jpg,image/png,image/svg',
            alt: { present: false, mandatory: false },
            defaultSize: {
                 height: 'auto',
                 width: 'auto',
            },
         },
       }}
       onEditorStateChange={this.onEditorStateChange}
/>

then define your uploadCallback if you want to read file directly from local

uploadCallback = (file) => {
        return new Promise(
            (resolve, reject) => {
                if (file) {
                    let reader = new FileReader();
                    reader.onload = (e) => {
                        resolve({ data: { link: e.target.result } })
                    };
                    reader.readAsDataURL(file);
                }
            }
        );
    }

Or if you want to use a file server to keep files then you might want to upload image on server and then simply put the link

uploadCallback = (file) => {
    return new Promise((resolve, reject) => {
       const data = new FormData();
       data.append("storyImage", file)
       axios.post(Upload file API call, data).then(responseImage => {
            resolve({ data: { link: PATH TO IMAGE ON SERVER } });
       })
    });
}
Clustered answered 4/7, 2020 at 17:3 Comment(1)
I followed this answer and was able to upload an image to my local server. But my client-side and server-side are two separate applications. One is a react (localhost:3000), the other is NodeJS (localhost:5000). I'd like to know if you have a way of getting the path to the image on the server from the client side. I've attempted using res.data after an api call, but it doesn't retrieve the image, it only retrieves data about the image.Outgrowth

© 2022 - 2024 — McMap. All rights reserved.