I used
- react-quill for one of form element.
- react-hook-form form validation
- yup/yup resolver for validation schema
Normal inputs and textareas working as expected, but validation for react-quill is not working.
These are my code snippets.
Custom react-quill wrapper element
import React, { useRef, useState } from "react";
import PropTypes from "prop-types";
import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";
import "react-quill/dist/quill.bubble.css";
import "react-quill/dist/quill.core.css";
function Editor(props) {
const [theme, setTheme] = useState("snow");
const { id, value, inputRef, placeholder, onChange } = props;
return (
<ReactQuill
id={id}
ref={inputRef}
theme={theme}
onChange={onChange}
value={value}
modules={{
toolbar: {
...Editor.modules.toolbar,
handlers: {
// image: handleImageUpload,
},
},
...Editor.modules,
}}
formats={Editor.formats}
bounds={".app"}
placeholder={placeholder ?? ""}
/>
);
}
/*
* Quill modules to attach to editor
* See / for plete options
*/
Editor.modules = {
toolbar: [
// [{ header: '1' }, { header: '2' }, { font: [] }],
// [{ size: [] }],
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
["bold", "italic", "underline", "strike", "blockquote"],
[
{ list: "ordered" },
{ list: "bullet" },
{ indent: "-1" },
{ indent: "+1" },
],
["link", "image", "video"],
["clean"],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
],
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
};
/*
* Quill editor formats
* See /
*/
Editor.formats = [
"header",
"font",
"size",
"bold",
"italic",
"underline",
"strike",
"blockquote",
"list",
"bullet",
"indent",
"link",
"image",
"video",
];
/*
* PropType validation
*/
Editor.propTypes = {
placeholder: PropTypes.string,
};
export default Editor;
This is form ponent
const validationSchema = Yup.object().shape({
panyName: Yup.string().required("Company Name is required"),
... ...
jobDescription: Yup.string().required("Job description is required"), // react-quill
... ...
howtoApply: Yup.string().required("This field is required"),
applyUrl: Yup.string().required("This field is required"),
applyEmail: Yup.string().required("This field is required"),
});
const formOptions = { resolver: yupResolver(validationSchema) };
const { register, handleSubmit, reset, control, formState } = useForm(
formOptions
);
useEffect(() => {
console.log("formState", formState); // log for form value changes
});
... ... ...
<Controller
control={control}
name="jobDescription"
// rules={{
// required: "Description must have some content.",
// validate: (value) => {
// console.log("Controller", value);
// return (
// value.split(" ").length > 10 ||
// "Enter at least 10 words in the body."
// );
// },
// }}
render={({
field: { onChange, onBlur, value, name, ref },
fieldState: { invalid, isTouched, isDirty, error },
formState,
}) => (
<Editor
onChange={(description, delta, source, editor) => {
console.log(
"onChange:description",
description,
);
console.log("inputRef", ref);
onChange(description);
}}
value={value || ""}
inputRef={ref}
theme="snow"
id="jobDescription"
/>
)}
/>
I checked these issues,
but still not working.
Current behavior
I confirmed the changed markdown logged in console (onChange function in Editor), but can't see formState log of useEffect hook upon editor change. (regardless of add rules prop to Controller or not)
Any help would be much appreciated
Thank you
I used
- react-quill for one of form element.
- react-hook-form form validation
- yup/yup resolver for validation schema
Normal inputs and textareas working as expected, but validation for react-quill is not working.
These are my code snippets.
Custom react-quill wrapper element
import React, { useRef, useState } from "react";
import PropTypes from "prop-types";
import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";
import "react-quill/dist/quill.bubble.css";
import "react-quill/dist/quill.core.css";
function Editor(props) {
const [theme, setTheme] = useState("snow");
const { id, value, inputRef, placeholder, onChange } = props;
return (
<ReactQuill
id={id}
ref={inputRef}
theme={theme}
onChange={onChange}
value={value}
modules={{
toolbar: {
...Editor.modules.toolbar,
handlers: {
// image: handleImageUpload,
},
},
...Editor.modules,
}}
formats={Editor.formats}
bounds={".app"}
placeholder={placeholder ?? ""}
/>
);
}
/*
* Quill modules to attach to editor
* See https://quilljs./docs/modules/ for plete options
*/
Editor.modules = {
toolbar: [
// [{ header: '1' }, { header: '2' }, { font: [] }],
// [{ size: [] }],
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
["bold", "italic", "underline", "strike", "blockquote"],
[
{ list: "ordered" },
{ list: "bullet" },
{ indent: "-1" },
{ indent: "+1" },
],
["link", "image", "video"],
["clean"],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
],
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
};
/*
* Quill editor formats
* See https://quilljs./docs/formats/
*/
Editor.formats = [
"header",
"font",
"size",
"bold",
"italic",
"underline",
"strike",
"blockquote",
"list",
"bullet",
"indent",
"link",
"image",
"video",
];
/*
* PropType validation
*/
Editor.propTypes = {
placeholder: PropTypes.string,
};
export default Editor;
This is form ponent
const validationSchema = Yup.object().shape({
panyName: Yup.string().required("Company Name is required"),
... ...
jobDescription: Yup.string().required("Job description is required"), // react-quill
... ...
howtoApply: Yup.string().required("This field is required"),
applyUrl: Yup.string().required("This field is required"),
applyEmail: Yup.string().required("This field is required"),
});
const formOptions = { resolver: yupResolver(validationSchema) };
const { register, handleSubmit, reset, control, formState } = useForm(
formOptions
);
useEffect(() => {
console.log("formState", formState); // log for form value changes
});
... ... ...
<Controller
control={control}
name="jobDescription"
// rules={{
// required: "Description must have some content.",
// validate: (value) => {
// console.log("Controller", value);
// return (
// value.split(" ").length > 10 ||
// "Enter at least 10 words in the body."
// );
// },
// }}
render={({
field: { onChange, onBlur, value, name, ref },
fieldState: { invalid, isTouched, isDirty, error },
formState,
}) => (
<Editor
onChange={(description, delta, source, editor) => {
console.log(
"onChange:description",
description,
);
console.log("inputRef", ref);
onChange(description);
}}
value={value || ""}
inputRef={ref}
theme="snow"
id="jobDescription"
/>
)}
/>
I checked these issues, https://github./zenoamaro/react-quill/issues/635
https://github./react-hook-form/react-hook-form/discussions/3372
but still not working.
Current behavior
I confirmed the changed markdown logged in console (onChange function in Editor), but can't see formState log of useEffect hook upon editor change. (regardless of add rules prop to Controller or not)
Any help would be much appreciated
Thank you
Share Improve this question asked Jun 15, 2021 at 9:32 Forest1206Forest1206 731 gold badge1 silver badge10 bronze badges 3- What is the current behavior? what is it doing? – Nemo Commented Jun 18, 2021 at 0:47
-
I have never used
formState
but first thing first, is this code in theform
tag? – Nemo Commented Jun 18, 2021 at 0:52 - sure, it's in form tag. – Forest1206 Commented Jun 18, 2021 at 12:56
3 Answers
Reset to default 8export default function App() {
const {
register,
handleSubmit,
setValue,
watch,
formState: { errors }
} = useForm();
useEffect(() => {
register("emailContent", { required: true, minLength: 15 });
}, [register]);
const onEditorStateChange = (editorState) => {
setValue("emailContent", editorState);
};
const onSubmit = (data) => {
console.log(data);
};
const editorContent = watch("emailContent");
return (
<div className="App">
<ReactQuill
theme="snow"
value={editorContent}
onChange={onEditorStateChange}
/>
<p className="Error">{errors.emailContent && "Enter valid content"}</p>
<input type="submit" onClick={handleSubmit(onSubmit)} />
</div>
);
}
I have created a code sandbox with a working example for react-hook-form. Here is the link:
https://codesandbox.io/s/quill-with-react-hook-form-validation-cdjru
<Controller
name="desc"
control={control}
rules={{
required: "Please enter task description",
}}
theme="snow"
modules={modules}
render={({ field }) => (
<ReactQuill
{...field}
placeholder={"Write Description"}
onChange={(text) => {
field.onChange(text);
}}
/>
)}
/>;
You Can Add Validator As ur like
you can try with "react-hook-form"
<FormField
control={form.control}
name="content"
render={({ field }) => (
<FormItem>
<FormLabel className="text-white">Picture</FormLabel>
<FormControl>
<ReactQuill
{...field}
ref={quillRef}
modules={modules}
theme="snow"
placeholder={"Write Description"}
className="mt-4 text-white"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
export const PostSchema: z.ZodType<PostType> = z.object({
id: z.number(),
shortDesc: z.string().min(4, "Minumun 4 in legnth"),
});