React Quill custom image handler not working - reactjs

Can someone help me to find out what is the issue in the code. I have created a custom image upload option but for some reason the variable "quillReact" is coming null when quillImageCallback function is invoked. I am using react-hooks. The image is uploaded properly when using API and proper response is also returned from the backend.
let quillReact: ReactQuill | null = null;
const updateIssueInfo = (value: string, delta: any, source: any, editor: any) => {
setIssueManagementInEdit({
...issueManagementInEdit,
description: value
});
};
const quillImageCallback = () => {
console.log(issueManagement);
const input = document.createElement("input");
input.setAttribute("type","file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file: File | null = input.files ? input.files[0] : null;
if(file){
uploadImage(file).then(async (fileName: any) => {
const newFileName:string = await fileName.text();
console.log(quillReact);
let quill: any | null = quillReact?.getEditor();
console.log(quill);
const range : any | null = quill?.getSelection(true);
quill?.insertEmbed(range.index, 'image', `http://localhost:8080/uploads/${newFileName}`);
});
}
}
};
const module = React.useMemo(() => { return {
toolbar: {
container: [
['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', 'image'] // remove formatting button
],
handlers: {
image: quillImageCallback
}
},
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
}
}},[]);
<ReactQuill
value={issueManagementInEdit.description ? issueManagementInEdit.description : ""}
onChange={updateIssueInfo}
modules={module}
ref={(el: ReactQuill) => {
quillReact = el;
} }
style={{height: "250px"}}
id="description"
key="description"
/>
Thank You.

I suggest you try useRef:
const quillRef = React.useRef(null);
<ReactQuill ... ref={quillRef} />
And then access the editor in your callback:
const quill = quillRef.current.getEditor();

Related

how can i set default text alignment in react-quill to right?

I want the default text-align to be right in react quill, i couldn't find a way to do that.
Here is my text editor:
import dynamic from 'next/dynamic'
import { ReactQuillProps } from 'react-quill'
import 'react-quill/dist/quill.snow.css'
const ReactQuill = dynamic(import('react-quill'), { ssr: false })
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ header: 1 }, { header: 2 }],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ direction: 'rtl' }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['link', 'image', 'video'],
['clean'],
]
export default function BasicTextEditor({
value,
onChange,
placeholder,
}: {
placeholder: string
value: string
onChange: () => void
}) {
const quillProps: ReactQuillProps = {
modules: {
toolbar: toolbarOptions,
},
}
return (
<ReactQuill
className="whitespace-pre-line"
{...quillProps}
placeholder={placeholder}
theme="snow"
value={value}
onChange={onChange}
formats={[{}]}
/>
)
}
As you can see there is an option called {align: []}, i want by default my text be
Right now for me to change the alignment of the text i have to add a class manly to each element in the text but i want a better way to achieve it.

quill js production problem in next js app

I am using quill JS with Next JS, its working totally fine on local machine but on production not working like when I selecting any header tag like h3 its by default selecting h1 tag
and when I selecting any color its not selecting it
Here is my component for quill js
RichTextEditor.js
import React from 'react'
import dynamic from 'next/dynamic'
const QullEditor = dynamic(import("react-quill"), {ssr: false})
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
['link'],
[{ '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
];
const RichTextEditor = ({ handler, defaultValue,placeholder }) => {
return (
<QullEditor modules={{toolbar:toolbarOptions}} onChange={(data) => handler(data)} theme="snow" placeholder={ placeholder ?? 'Enter Your Paragraph'} defaultValue={defaultValue} />
)
}
export default RichTextEditor
and I am using it like this
<RichTextEditor handler={setSubText} defaultValue={update.is ? update.data.subtext : null} />
Please Let me know How to solve this bug

React quill in nextjs and typescript custom image handler issue?

I am try to use react-quill in my typescript nextjs project. Here I am finding typing and ref issue that I can't solve. Please help me.
Here is code example-
import React, { useState, useRef } from 'react';
import dynamic from 'next/dynamic';
import { Container } from "#mui/material";
const ReactQuill = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
})
import 'react-quill/dist/quill.snow.css';
const Editor = () => {
const [value, setValue] = useState('');
const quillRef = useRef<any>();
const imageHandler = async () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = async () => {
var file: any = input && input.files ? input.files[0] : null;
var formData = new FormData();
formData.append("file", file);
let quillObj = quillRef.current.getEditor();
};
}
const modules = {
toolbar: {
container: [
[{ font: [] }, { 'size': [] }, { 'header': [1, 2, 3, 4, 5, 6] }],
['bold', 'italic', 'underline', 'strike'],
[{ 'color': [] }, { 'background': [] }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'header': 1 }, { 'header': 2 }, 'blockquote', 'code-block'],
[
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
[{ 'direction': 'rtl' }, { 'align': [] }],
['link', 'image', 'clean'],
],
'handlers': {
image: imageHandler
}
}
}
return (
<Container maxWidth="xxxl" disableGutters>
<ReactQuill
ref={quillRef} // Here I am finding an issue.
value={value}
modules={modules}
onChange={setValue}
placeholder="Start typing!"
/>
</Container>
);
};
export default Editor;
Here is CodeSandBox-
https://codesandbox.io/s/still-hill-xkb1pj
Can any one give me a proper typescript solutions.

React infinite loop caused by onChange on Inputfield / React Quill

im new to react and just have to update a value in onChange to filter some tags. But When I do that, it causes an infinite loop. How can I prevent that?
const Editor = ({ onChange, name, value }) => {
const modules = {
toolbar: [
[{ 'header': '1'}, {'header': '2'}, { 'font': [] }],
[{size: []}],
['bold', 'italic', 'underline','strike', 'blockquote'],
[{'list': 'ordered'}, {'list': 'bullet'}, {'indent': '-1'}, {'indent': '+1'}],
['link'],
['clean']
],
clipboard: {
matchVisual: false
}
}
return (
<ReactQuill
theme="snow"
value={value}
modules={modules}
onChange={(content, event, editor) => {
const cleanedContent = content?.replace(/<p><br><\/p>/g, '<br>');
console.log('test');
onChange({ target: { name, value: cleanedContent } });
}}/>
);
};
export default Editor;

QuillJS - Anyone can supply customized code for full toolbar with headers applied only for selections and not the entire text? Coldfusion and QuillJS

Need a working QUILLJS code with has full toolbar and a working Header icons in the toolbar to be applied only to the selected text and not to the entire text.
I am trying to avoid lot of recoding moving from a paid CKEditor into free QUILLJS.
HTML:
<div id="editor-container" style="height: 350px;">#variables.valTextSettings[url.msg]#</div>
<textarea id="htmlMessage" name="htmlMessage" style="display:none;"></textarea>
JS:
the html is handled via a hidden variable
$(document).ready(function () {
var quillcontainter = '#editor-container';
var hiddenformfield = '#htmlMessage';
var quill = new Quill(quillcontainter, {
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
[{ 'font': [] }],[{ 'color': [] }, { 'background': [] }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'header': 1 }, { 'header': 2 }],
['blockquote', 'code-block'],
[{ 'script': 'sub'}, { 'script': 'super' }],
[{ 'align': [] }],
['link'],
['clean'],
['showHtml']
]
},
placeholder: 'Transaction Notes..',
theme: 'snow' // or 'bubble'
});
/* Load Default values */
$(hiddenformfield).html(quill.root.innerHTML);
// This will produce a warning message in the console as we are attaching handlers separately, but we can ignore
var txtArea = document.createElement('textarea');
txtArea.style.cssText = "width: 100%;margin: 0px;background: rgb(29, 29, 29);box-sizing: border-box;color: rgb(204, 204, 204);font-size: 15px;outline: none;padding: 20px;line-height: 24px;font-family: Arial, Helvetica, sans-serif;position: absolute;top: 0;bottom: 0;border: none;display:none";
var htmlEditor = quill.addContainer('ql-custom'); htmlEditor.appendChild(txtArea);
var myEditor = document.querySelector(quillcontainter);
quill.on('text-change', function (delta, old, source) {
txtArea.value = quill.root.innerHTML;
$(hiddenformfield).html(quill.root.innerHTML);
});
var customButton = document.querySelector('.ql-showHtml');
customButton.addEventListener('click', function() {
if (txtArea.style.display === '') { var html = txtArea.value; quill.pasteHTML(html); }
// No text change but clicking the Source button
else { var html = quill.root.innerHTML; quill.pasteHTML(html); }
txtArea.style.display = txtArea.style.display === 'none' ? '' : 'none'
});
});

Resources