Ngx-quill: Handler for image upload

Created on 2 Jan 2018  Â·  10Comments  Â·  Source: KillerCodeMonkey/ngx-quill

Can you please let me know the image upload handler. I would need to upload the image to another server, so getting the callback for image selected would enable me to upload image to a different server rather than adding the base64 encoded data.

question

Most helpful comment

doc004

All 10 comments

this is more likely a quilljs question, but here we go:

An image handler is a simple javascript function. you have two different approaches:

  1. pass the handler through your modules config like:
{
  toolbar: {
    image: function () { ... }
  } 
}
  1. add the handler after editor creation:
  • listen on the onEditorCreated output
  • grab the output data ($event) = the quill editor instance
var toolbar = quillInstance.getModule('toolbar');
toolbar.addHandler('image', myHandlerFunction);

Described also here with examples:
https://quilljs.com/docs/modules/toolbar/#handlers

and 3.

here is even an issue in the quilljs repo https://github.com/quilljs/quill/issues/1400

Hi

I seem to have implemented the editor in a different way. Do let me know if this is the right way.

In the module file, added the QullModule after importing it like:

import { QuillModule } from 'ngx-quill';


@NgModule({
  imports: [
  QuillModule
  ]

Then in the HTML:

    <quill-editor placeholder="Add case note here" formControlName="note" [style]="{height: '300px'}">
    </quill-editor>

So where do I add the toolbar handler and i am not initializing the editor also to get the onEditorCreated instance.

Do assist.

simply check my demo how you can listen on the outputs like onEditorCreated
https://github.com/KillerCodeMonkey/ngx-quill-example/blob/master/src/app.component.ts

<quill-editor
  (onEditorCreated)="getEditorInstance($event)"

  placeholder="Add case note here"
  formControlName="note"
  [style]="{height: '300px'}">
</quill-editor>
getEditorInstance(editorInstance:any) {
  console.log(editorInstance)
  let toolbar = editorInstance.getModule('toolbar');
  toolbar.addHandler('image', showImageUI);
}

or you can use the modules input to configure your editor instance:

<quill-editor
  placeholder="Add case note here"
  formControlName="note"
  [style]="{height: '300px'}"

  [modules]="{
    toolbar: { image: YOUR_HANDLER_FUNCTION }
  }"
>
</quill-editor>

@KillerCodeMonkey: This is great. I missed the documentation for the same.
Let me rephrase myself.

The original image upload that is there in the editor is perfect. I just want to get the image selected after the user has uploaded the image by browsing through the local machine. Currently its embedded into the editor as a base64 string.

Is there anyway to get an event like imageSelected ?

Uhhh i do not know how you can achieve this. There is also an
onSelectionChanged input in ngx-quill maybe there you get the information
if the image is added.

In and other cases check if you find something in the quilljs doc or ASK
directly there :).

Thanks

Am 03.01.2018 10:47 vorm. schrieb "Roy M J" notifications@github.com:

@KillerCodeMonkey https://github.com/killercodemonkey: This is great. I
missed the documentation for the same.
Let me rephrase myself.

The original image upload that is there in the editor is perfect. I just
want to get the image selected after the user has uploaded the image by
browsing through the local machine.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/KillerCodeMonkey/ngx-quill/issues/89#issuecomment-354971900,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACKOYCP4MRI69G-gH9K-YZnOpW4V8xDrks5tG0ysgaJpZM4RQkU1
.

@KillerCodeMonkey how would you pass the image handler if the module is formatted like the following?

modules = {
      toolbar: [
        ['bold', 'italic', 'underline', 'strike'], // toggled buttons
        ['blockquote', 'code-block'],

        [{ header: 1 }, { header: 2 }], // custom button values
        [{ list: 'ordered' }, { list: 'bullet' }],
        [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
        [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
        [{ direction: 'rtl' }], // text direction
        [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
        [{ header: [1, 2, 3, 4, 5, 6, false] }],

        [{ color: [] }, { background: [] }], // dropdown with defaults from theme
        [{ font: [] }],
        [{ align: [] }],

        ['clean'], // remove formatting button
        ['link', 'image', 'video'], // link and image and video
      ],
      imageResize: true
    }

https://quilljs.com/docs/modules/toolbar/ ;)

modules: {
    toolbar: {
      container: '#toolbar',  // Selector for toolbar container
      handlers: {
        'bold': customBoldHandler
      }
    }
  }

and pass a handler function or function reference to the handler.

doc004

I want to upload the image to my server after selection of image ! is this possible ?

I have found a way to upload the image to your server and then show it in the editor.

I will write code bellow, but first I will explain shortly how I did it. The solution includes a custom image upload handler for quill editor, as well as an extra input field of type file ( if you had trouble understanding what I just wrote, I know I did :) ). Anyway here is the code

component.css

.invisible-input-cont input {
    width: 0px;
    height: 0px;
}

component.html

Put following two elements anywhere you like in your component.html
...
<div class="invisible-input-cont">
    <input #quillFile type="file" (change)="quillFileSelected($event)">
  </div>
...
<quill-editor #meQuill [modules]="editorModules" name="htmlText"
              (onEditorCreated)="getMeEditorInstance($event)"
              [formControl]="articleForm.get('me').get('htmlText')"></quill-editor>

component.ts

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { FormControl, FormGroup, FormBuilder, FormArray, Validators } from '@angular/forms';
import * as QuillNamespace from 'quill';
const Quill: any = QuillNamespace;
import ImageResize from 'quill-image-resize-module';
Quill.register('modules/imageResize', ImageResize);

@Component({
  selector: 'app-my-quill-upload',
  templateUrl: './my-quill-upload.component.html',
  styleUrls: ['./my-quill-upload.component.css']
})
export class MyQuillUploadComponent implements OnInit {

@ViewChild('quillFile') quillFileRef: ElementRef;
  quillFile: any;
  meQuillRef: any;
  editorModules = {
    toolbar: {
      container: [
        [{ font: [] }],
        [{ size: ['small', false, 'large', 'huge'] }],
        ['bold', 'italic', 'underline', 'strike'],
        [{ header: 1 }, { header: 2 }],
        [{ color: [] }, { background: [] }],
        [{ list: 'ordered' }, { list: 'bullet' }],
        [{ align: [] }],
        ['link', 'image']
      ],
      handlers: {
        image: (image) => {
          this.customImageUpload(image);
        }
      }
    },
    imageResize: true,
  };

constructor(private fb: FormBuilder,
              private dataService: DataService) { }

ngOnInit() {
     this.createForm();
  }

getMeEditorInstance(editorInstance: any) {
    this.meQuillRef = editorInstance;
  }

customImageUpload(image: any) {
    console.log(image);
    /* Here we trigger a click action on the file input field, this will open a file chooser on a client computer */
    this.quillFileRef.nativeElement.click();
  }

 quillFileSelected(ev: any) {
   /* After the file is selected from the file chooser, we handle the upload process */
    this.quillFile = ev.target.files[0];
    console.log(ev.target.files[0]);
    const imageData = {
      id: this.article != null && this.article !== undefined ? this.article.post_id : null,
      title: this.quillFile.name,
      file: this.quillFile
    };
  this.dataService.postImage(imageData).subscribe(
      (response: any) => {
        console.log(response);
        const filename = response.data.filename;
        let range: any;
        const img = '<img class="img-within" src="your_upload_directory_here/' + filename + '"></img>';
        range = this.meQuillRef.getSelection();
        this.meQuillRef.clipboard.dangerouslyPasteHTML(range.index, img);
      }
    );
  }
}

data.service.ts

/* I am using id and title fields for my own needs, to store data in my database on backend, you can remove them if you want */
postImage(imageData: {id: number, title: string, file: any}): Observable<any> {
    const url = this.baseUrl + 'images';
    const formData = new FormData();
    if (imageData != null && imageData.id != null) {
      formData.append('id', imageData.id + '');
    }

    if (imageData != null && imageData.title != null) {
      formData.append('title', imageData.title);
    } else {
      formData.append('title', 'dhm_' + Math.round(Math.random() * 100000000));
    }

    formData.append('fileupload', imageData.file);
    return this.http.post(url, formData).pipe(map(
        (results) => results));
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

anthonyinspace picture anthonyinspace  Â·  3Comments

SebastianPodgajny picture SebastianPodgajny  Â·  4Comments

anshumandikshit picture anshumandikshit  Â·  3Comments

theCrius picture theCrius  Â·  3Comments

tommueller picture tommueller  Â·  3Comments