React-quill: image handler

Created on 8 Mar 2017  路  11Comments  路  Source: zenoamaro/react-quill

version: 1.0.0-beta-3

Hi, can someone give me how to manage image handler ?
I referred Quill document but the version was different.

New image handler returns image, callback like below link
http://codepen.io/jackmu95/pen/EgBKZr?editors=0010

However image handler im using with v1.0.0-beta-3 is not returning the same value.

My requirement is following

  1. open file selector
  2. Get the image
  3. Upload image to my server
  4. Then return <img src="" /> element

If there is any example that would be great

Most helpful comment

In case anyone is still wondering how to solve this. I managed to implement a custom imageHandler function with the following approach:

this.modules = {
    formula: true,
        toolbar: {
            container:  [['bold', 'italic', 'underline', 'blockquote'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                ['formula','link', 'image'],
                ['clean']],
         handlers: {
             'image': this.imageHandler
        }
    }
};

And with the following imageHandler function:

imageHandler = (image, callback) => {
    var range = this.quillRef.getEditor().getSelection();
    var value = prompt('What is the image URL');
    if(value) {
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, "user");
    }
}

Make sure that you add ref={(el) => this.quillRef = el} to the ReactQuill JSX element.

You can then do whatever you want in your imageHandler function. You could implement an upload function or whatever you want to do with your image, before displaying it.

All 11 comments

That API is not available in the mainline Quill branch. See this open PR by the author of your Codepen link: https://github.com/quilljs/quill/pull/995

Yeah I know it is not supported but I believe I can use handler to customize it.
Problem is image handler is not passing same parameters as quilljs/quill#995

When I try like code below, it only returns boolean value

toolbar: {
         container: [
              ['bold', 'italic', 'underline', 'strike', 'blockquote'],
              [{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}],
              ['link', 'image'],
              ['clean']
          ],
          handlers: {
               // handlers object will be merged with default handlers object
            'image': this.imageHandler
         }
 }
  1. React-Quill just passes the modules prop to Quill.
  2. The toolbar handlers simply hook into the click events for the buttons. You need to provide everything after that, like using the Quill insertText API or changing the selection. The API in that PR doesn't reflect what happens when you press the button because it is trying to intercept the Quill image insertion function, which happens after the button is hit.
  3. Given that info, you might be able to use this example to create a custom callback that does what you want, and then calls the regular API with the image: http://codepen.io/alexkrolick/pen/gmroPj

In case anyone is still wondering how to solve this. I managed to implement a custom imageHandler function with the following approach:

this.modules = {
    formula: true,
        toolbar: {
            container:  [['bold', 'italic', 'underline', 'blockquote'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                ['formula','link', 'image'],
                ['clean']],
         handlers: {
             'image': this.imageHandler
        }
    }
};

And with the following imageHandler function:

imageHandler = (image, callback) => {
    var range = this.quillRef.getEditor().getSelection();
    var value = prompt('What is the image URL');
    if(value) {
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, "user");
    }
}

Make sure that you add ref={(el) => this.quillRef = el} to the ReactQuill JSX element.

You can then do whatever you want in your imageHandler function. You could implement an upload function or whatever you want to do with your image, before displaying it.

I have been able to get a custom image handler to work using these guidelines, but can't figure out how to add an alt attribute to the embed. I have the alt text saved in state (and in the DB as part of the image object) but can't figure out how to insert it into the html. insertEmbed doesn't seem to accept anything but the value (url string). Any ideas how to to this?

You might want to file that question upstream - it's not something that ReactQuill would handle but rather Quill itself.

In case anybody else is also trying to add alt text to the embedded image, I ended up solving this by using a custom image blot, which is an extension of BlockEmbed (rather than trying to do it with insertEmbed)

import React, { Component } from 'react';
import ReactQuill from 'react-quill';

// / Custom ImageBlot to add alt text to inline images / ///

const Quill = ReactQuill.Quill;
const BlockEmbed = Quill.import('blots/block/embed');

class ImageBlot extends BlockEmbed {
  static create(value) {
    const node = super.create();
    node.setAttribute('alt', value.alt);
    node.setAttribute('src', value.url);
    return node;
  }

  static value(node) {
    return {
      alt: node.getAttribute('alt'),
      url: node.getAttribute('src'),
    };
  }
}
ImageBlot.blotName = 'image';
ImageBlot.tagName = 'img';
ImageBlot.className = 'inline-img';
Quill.register(ImageBlot);

@miczed Your code works in the official (master branch) version?

In case anyone is still wondering how to solve this. I managed to implement a custom imageHandler function with the following approach:

this.modules = {
    formula: true,
        toolbar: {
            container:  [['bold', 'italic', 'underline', 'blockquote'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                ['formula','link', 'image'],
                ['clean']],
         handlers: {
             'image': this.imageHandler
        }
    }
};

And with the following imageHandler function:

imageHandler = (image, callback) => {
    var range = this.quillRef.getEditor().getSelection();
    var value = prompt('What is the image URL');
    if(value) {
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, "user");
    }
}

Make sure that you add ref={(el) => this.quillRef = el} to the ReactQuill JSX element.

You can then do whatever you want in your imageHandler function. You could implement an upload function or whatever you want to do with your image, before displaying it.

I'm having an error where I have multiple input fields and for some reason, when it sets state on the previous input field, it automatically jumps the cursor to the React Quill textbox. ie. imagine I have an input with an onChange(event => { ...sets state }). This onChange event for some reason then automatically switches the cursor from this input to my React Quill input. Any chance you might know how to fix this?

@hariria change the functional component to class component and make this.modules to all the quill modules solve the problem for me

In case anyone is still wondering how to solve this. I managed to implement a custom imageHandler function with the following approach:

this.modules = {
    formula: true,
        toolbar: {
            container:  [['bold', 'italic', 'underline', 'blockquote'],
                [{'list': 'ordered'}, {'list': 'bullet'}],
                ['formula','link', 'image'],
                ['clean']],
         handlers: {
             'image': this.imageHandler
        }
    }
};

And with the following imageHandler function:

imageHandler = (image, callback) => {
    var range = this.quillRef.getEditor().getSelection();
    var value = prompt('What is the image URL');
    if(value) {
        this.quillRef.getEditor().insertEmbed(range.index, 'image', value, "user");
    }
}

Make sure that you add ref={(el) => this.quillRef = el} to the ReactQuill JSX element.

You can then do whatever you want in your imageHandler function. You could implement an upload function or whatever you want to do with your image, before displaying it.

When following this approach a weird thing is happening.
Post any key press the focus is lost from the editor.
Codepen link

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Nazanin1369 picture Nazanin1369  路  4Comments

camliu89 picture camliu89  路  4Comments

LiuChangFreeman picture LiuChangFreeman  路  3Comments

aliciawood picture aliciawood  路  3Comments

sophyphreak picture sophyphreak  路  5Comments