Rich Text Control With Image And Video In SPFx Using React-Quill

Introduction

 
Rich Text Control is one of the most-used controls in classic SharePoint Lists but if we need to create a customization for Modern SharePoint List form using SharePoint Framework there is no easy way to do so. But in this article, we will understand how we can use react-quill control to save the rich text field and also display it for the existing items.
 
react-quill is based on Quill which is trusted by Microsoft. To know more about the react-quill control please check the below link.
 
So let us understand how we can use react-quill in our Custom SharePoint List Form.
 
Step 1 - Create a List
 
Before creating a Custom form we would create a SharePoint list for saving the data.
 
List Name:- Custom RichText
Columns:- Title(Single Line of Text)
Description(Multi-Line of Text in Plain Text format)
 
Note
We are using Plain Text but we will save the HTML in it because the images in React quill will be converted in base64 and will get truncated in Rich Text format.
 
Step 2 - Create SPFx Solution
 
Considering we have the environment setup completed we can use the below command to create new SPFx solution. We will use React framework for creating the Webpart
  1. yo @microsoft/sharepoint  
Use the below values when asked while creating the solution.
 
Rich Text Control With Image And Video In SPFx Using React-Quill
 
Step 3 - Add the reference for react-quill
 
To add a reference to React quill in our project we need to use the below command which would install the required dependencies in our solution.
  1. npm install react-quill --save  
Saving the data we would use PnPJs so let us install the required dependencies for PnPJs.
  1. npm install @pnp/sp --save  
Rich Text Control With Image And Video In SPFx Using React-Quill
 
Step 4 - Update the WebPart Code
 
Now that we have all the dependencies added in our solution we can update the code.
 
Let us set up the sp object so that we can use it to save the list item and retrieve it.

Open the file name named RichTextFieldWebPart.ts.
 
Import sp using the below code.
  1. import { sp } from "@pnp/sp/presets/all";  
And add the below function to setup sp object.
  1. protected onInit(): Promise<void> {  
  2.    return super.onInit().then(_ => {  
  3.       sp.setup({  
  4.          spfxContext: this.context  
  5.       });  
  6.    });  
  7. }  
Open the file named RichTextField.tsx to update the code for the rich text field.
 
Let us add the required reference for React quill using the below code.
  1. import ReactQuill from 'react-quill';  
  2. import 'react-quill/dist/quill.snow.css';  
Let us now create and  add required interfaces.
  1. export interface ICustomRichText {  
  2.     Title: string;  
  3.     Description: string;  
  4. }  
  5. export interface IRichTextFieldWebPartState {  
  6.     item: ICustomRichText;  
  7. }  
Now for using react quill we can use custom toolbar so we would add all the required toolbar using the below constant:
  1. const modules = {  
  2.     toolbar: [  
  3.         [{  
  4.             'header': [1, 2, 3, false]  
  5.         }],  
  6.         ['bold''italic''underline''strike''blockquote'],  
  7.         [{  
  8.             'color': []  
  9.         }, {  
  10.             'background': []  
  11.         }],  
  12.         [{  
  13.             'list''ordered'  
  14.         }, {  
  15.             'list''bullet'  
  16.         }, {  
  17.             'indent''-1'  
  18.         }, {  
  19.             'indent''+1'  
  20.         }],  
  21.         ['link''image''video'],  
  22.         ['clean']  
  23.     ],  
  24. };  
  25. const formats = ['header''bold''italic''underline''strike''blockquote''list''bullet''indent''link''image''video''background''color'];  
Now in the render method of the component, we will have to add the below code which contains one text field and one React quill text editor:
  1. <div className={styles.column}>    
  2.     
  3. <div>Title</div>    
  4.    <input type="text" value={this.state.item.Title} onChange={(ev) => {    
  5.    this.setState({ item: { Title: ev.target.value, Description: this.state.item.Description } });    
  6.    }}></input>    
  7. </div>    
  8. <div className={styles.column}>    
  9.     
  10. <div>Description</div>    
  11.    <ReactQuill theme="snow"    
  12.       modules={modules}    
  13.       formats={formats}    
  14.       value={this.state.item.Description}    
  15.       onChange={(ev) => {    
  16.       this.setState({ item: { Title: this.state.item.Title, Description: ev } });    
  17.    }}    
  18.    ></ReactQuill>    
  19. </div>    
  20. <div className={styles.column}>    
  21. <button onClick={this.saveClick}>Save Item</button>    
  22. </div>    
For saving the data and all the on change functions we need to add the below code:
  1. constructor(props: IRichTextFieldWebPartProps, state: IRichTextFieldWebPartState) {  
  2.     super(props);  
  3.     var queryParameters = new UrlQueryParameterCollection(window.location.href);  
  4.     if (queryParameters.getValue("itemid")) {  
  5.         const id: number = parseInt(queryParameters.getValue("itemid"));  
  6.         sp.web.lists.getByTitle('Custom RichText').items.getById(id).get().then((val: ICustomRichText) => {  
  7.             this.setState({  
  8.                 item: {  
  9.                     Title: val.Title,  
  10.                     Description: val.Description  
  11.                 }  
  12.             });  
  13.         }).catch((err) => {  
  14.             console.error(err);  
  15.         });  
  16.     }  
  17.     this.state = {  
  18.         item: {  
  19.             Title: "",  
  20.             Description: ""  
  21.         }  
  22.     };  
  23. }  
  24. public saveClick = () => {  
  25.     sp.web.lists.getByTitle('Custom RichText').items.add(this.state.item).then((val) => {  
  26.         alert('Item Saved');  
  27.     }).catch((err) => {  
  28.         console.error(err);  
  29.     });  
  30. }  
We are also fetching the item with the query string value of itemid to display the value of the existing saved item.
 
So once all of the code is updated we can test our Webpart which would save the data and also display the saved item. We can save images videos and all text formatting which are available.
 
Outcome
 
 

Conclusion

 
For rich text field in SPFx react quill can be one of the best controls which can be used for saving the rich text field.

This will even help us save images and videos in the rich text field in SharePoint List.