React Quill Custom image handler
Kartik0899 opened this issue · 4 comments
Kartik0899 commented
I am working with react-quill and my image handler is not working below is my code --
The error I'm getting is TypeError: quillRef.current.getEditor is not a function
import dynamic from "next/dynamic";
import "react-quill/dist/quill.snow.css";
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
const handleEditorImageUpload = async () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file = input.files[0];
const uploadedImage = await uploadImage(file);
if (uploadedImage) {
let quill = quillRef.current.getEditor();
const range = quill.getSelection();
quill.insertEmbed(range.index, "image", uploadedImage.url);
}
};
};
let toolbarOptions = [
[{ header: [1, 2, 3, 4, 5, 6] }, { font: [] }],
[{ list: "ordered" }, { list: "bullet" }],
["bold", "italic", "underline", "strike"],
["image"],
];
const modules = useMemo(
() => ({
toolbar: {
container: toolbarOptions,
handlers: { image: handleEditorImageUpload },
},
}),
[]
);
<ReactQuill
ref={quillRef}
value={body}
onChange={setBody}
modules={modules}
placeholder="Write your blog content here..."
/>
It is giving me an error of getEditor
Error - TypeError: quillRef.current.getEditor is not a function
Any help would be much appreciated!
tjiptostevens commented
have you declared the quillRef..?
this code below work fine with me.
import { useMemo, useRef } from "react";
. . .
const quillRef = useRef(null);
const handleImageInserted = async (file) => {
try {
const compressedImage = await compressImage(file); // compress the image
const imageUrl = await handleFsImageUpload(path, compressedImage); // upload to server
const quill = quillRef.current.getEditor();
const range = quill.getSelection();
quill.insertEmbed(range.index, "image", imageUrl); // add an img tag to quill
} catch (error) {
console.error("Error handling image insertion:", error);
}
};
const openImageFileDialog = () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.onchange = (event) => {
const file = event.target.files[0];
if (file) {
handleImageInserted(file);
}
};
input.click();
};
. . .
Kartik0899 commented
Hey @tjiptostevens,
I tried using the code you provided but I am still getting the same error -
Error - Error handling image insertion: TypeError: quillRef.current.getEditor is not a function at handleImageInserted
Below is the dependencies -
"react": "^18",
"react-dom": "^18",
"react-quill": "^2.0.0",
tjiptostevens commented
hhmm... how about this code. this work for me
import { useMemo, useRef, useState } from "react";
import dynamic from "next/dynamic";
import "react-quill/dist/quill.snow.css";
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
const TextEditor = ({ path = "/" }) => {
const [body, setBody] = useState("");
const quillRef = useRef(null);
const handleImageInserted = async (file) => {
try {
const imageUrl = await handleFsImageUpload(path, file); // image upload function
const quill = quillRef.current.getEditor();
const range = quill.getSelection();
quill.insertEmbed(range.index, "image", imageUrl);
} catch (error) {
console.error("Error handling image insertion:", error);
}
};
const openImageFileDialog = () => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.onchange = (event) => {
const file = event.target.files[0];
if (file) {
handleImageInserted(file);
}
};
input.click();
};
const handleChange = (value) => {
setBody(value);
};
const quillModules = useMemo(
() => ({
toolbar: {
container: [
["bold", "italic", "underline", "strike"],
[{ header: "1" }, { header: "2" }],
[{ list: "ordered" }, { list: "bullet" }],
["link", "image", "youtube"],
],
handlers: {
image: openImageFileDialog,
},
},
}),
[]
);
return (
<div className="form-group __texteditor">
<label htmlFor="category">
Content <b>*</b>
</label>
<ReactQuill
ref={quillRef}
value={body}
onChange={handleChange}
theme="snow"
modules={quillModules}
/>
</div>
);
};
export default TextEditor;