In my previous article I have described how to integrate Rich Text Editor in SharePoint Framework (SPFx) Angular webparts. Now let’s see how do we implement custom image handler in the same, so you could be able to save the images uploaded in Rich Text Editor to the desired destination folder.

Let’s directly go to the implementation with the below steps,

Get the ngx-quill editor instance.

Once the editor created/rendered in your view, we will need to get the ngx-quill editor instance. It will be helpful to add our custom handlers to the controls in the editor or even you could add your own custom controls.

Use onEditorCreated event to get the editor instance. Please find below code snippet,

Component html file:

<quill-editor [(ngModel)]=”DescriptionHF” (onEditorCreated)=”editorCreated($event)”>

</quill-editor> 

Component ts file:

private editorInstance: any;

private editorCreated(quill: any) {

        this.editorInstance = quill;

        var toolbar = this.editorInstance.getModule(‘toolbar’);

        toolbar.addHandler(‘image’, this.imageEditorHandler.bind(this));

    } 

This event will be raised once the editor created in the page, so we will have access to the toolbar of the quill editor.  In the second line of the method we get the toolbar module in the variable toolbar. Image control name in the quill toolbar is image. In the toolbar instance we do have a method to add handlers.

Leaderboard_CDR

The last line of code in the above method demonstrates how to register the custom image handler in quill-editor toolbar.

How to get current page context in the quill editor handler method?

If you notice in the above method, highlighted content bind(this) will get you the current page context inside the handler whenever an image icon is clicked in the quill editor toolbar.

How to insert the selected image in quill editor using image handler?

Once we are into the handler method the first thing we need to do is to get the selection range, i.e, to get the cursor range so we could insert the image where the cursor points to. To get the range of index use the below line of code in the handler,

const range = this.editorInstance.getSelection();

Now let’s popup the image selection window using the default image control in the html.  Create image control dynamically inside the handler and use it’s change event to process the selected image.

Please find the below handler method with all the functionalities,

private imageEditorHandler() {

        if (this.editorInstance!=null)) {

            const range = this.editorInstance.getSelection();

            if (range!=null) {

                let input = document.createElement(‘input’);

                input.setAttribute(‘type’, ‘file’);

                input.setAttribute(‘accept’, ‘image/*’);

                input.addEventListener(‘change’, () => {

                    if (input.files!=null) {

                        let file = input.files[0];

                        if (file!=null) {

var reader = new FileReader();

reader.readAsDataURL(file);

reader.onerror = function (error) {

console.log(‘Error: ‘, error);

};

reader.onloadend = function () {

            //Read complete

   if (reader.readyState == 2) {

      var base64result = reader.result;

     //Write your code to upload image in your custom location

            }

        };

                         }

                    }

                });

                input.click();

            }

        }

    }

The change event listener should be registered before clicking the dynamically created file control.

We will be using FileReader to read the file and convert it into a base64 string and in the above code snippet we got base64String in the variable base64result.

Once we got the base64string you can insert the image in the editor by using the insertEmbed method of quill editor instance like below,

this.editorInstance.insertEmbed(range.index, ‘image’, base64result);

In the above line if you notice range.index which is used to insert the image

at the appropriate location in the editor.

How to save the image in a library in SPFx?

SharePoint provides lot of rest API endpoints which could be helpful to manipulate data in SharePoint,

The following blog posts will help you for sure in detail about handling lists and Groups in SPFx using SPFx,

  1. How to manage SharePoint Groups using REST API in SharePoint Framework (SPFx)

Now, let’s see how to upload image to SharePoint from SPFx using Rest API.

Method: POST

URL: {ReplaceYourSiteUrl}/ /_api/web/GetFolderByServerRelativeUrl(‘{ServerRelativeUrlOfFolder}’)/Files/add(url='{FileName}’,overwrite=true)

let requestUrl = currentWebUrl.concat(“/_api/web/GetFolderByServerRelativeUrl(‘{ServerRelativeUrlOfFolder}’)/Files/add(url='{FileName}’,overwrite=true)”);

let spOpts = {

            headers: {

                “Accept”: “application/json;”,

                “Content-Type”: “multipart/form-data”,

                ‘Content-Length’: “”

            },

            body: FileObject

        };

this.context.spHttpClient.post(requestUrl, SPHttpClient.configurations.v1,spOpts);

The beauty is you no need to pass the base64 to this api, you can direcrlty pass the FileObject selected from the file control. Since we are mentioning content-type as multipart/form-data in API Request, SharePoint will handle it for you.

This article describes just a sample about integrating the custom image handler in ngx-quill editor and how to insert it in the cursor point position and upload it in desired location in SharePoint

If you have any questions/issues about this article, please let me know in comments.