-
-
Save AndersonNascimentoDosSantos/b3b8f760f3a431fe9e0ee440f5b0e2d4 to your computer and use it in GitHub Desktop.
"use client"; | |
import { Button } from "@/components/ui/button"; | |
import { | |
Form, | |
FormControl, | |
FormField, | |
FormItem, | |
FormLabel, | |
FormMessage, | |
} from "@/components/ui/form"; //shadcn ui folder | |
import { cn } from "@/lib/utils"; | |
import { zodResolver } from "@hookform/resolvers/zod"; | |
import { useState } from "react"; | |
import { useForm } from "react-hook-form"; | |
import { BsImages, BsPaperclip } from "react-icons/bs"; | |
import { IoSendOutline } from "react-icons/io5"; | |
import * as z from "zod"; | |
const MAX_FILE_SIZE = 1024 * 1024 * 5; | |
const ACCEPTED_IMAGE_MIME_TYPES = [ | |
"image/jpeg", | |
"image/jpg", | |
"image/png", | |
"image/webp", | |
]; | |
const ACCEPTED_IMAGE_TYPES = ["jpeg", "jpg", "png", "webp"]; | |
const formSchema = z.object({ | |
adImage: z | |
.any() | |
.refine((files) => { | |
return files?.[0]?.size <= MAX_FILE_SIZE; | |
}, `Max image size is 5MB.`) | |
.refine( | |
(files) => ACCEPTED_IMAGE_MIME_TYPES.includes(files?.[0]?.type), | |
"Only .jpg, .jpeg, .png and .webp formats are supported." | |
), | |
}); | |
export type ContactFormData = z.infer<typeof formSchema>; | |
export default function Home() { | |
const [selectedImage, setSelectedImage] = useState<File | null>(null); | |
const form = useForm<ContactFormData>({ | |
resolver: zodResolver(formSchema), | |
defaultValues: { | |
adImage: undefined, | |
}, | |
}); | |
const onSubmit = async (data: ContactFormData) => { | |
console.log(data); | |
}; | |
return ( | |
<main className="flex min-h-screen flex-col items-center justify-between p-24"> | |
<Form {...form}> | |
<form onSubmit={form.handleSubmit(onSubmit)}> | |
<div className={cn("flex md:flex-row w-[100%] gap-4 flex-col")}> | |
<div className="flex w-[100%] gap-4 flex-col "> | |
<FormLabel>your form title</FormLabel> | |
<div | |
className={`flex w-[100%] gap-4 p-4 rounded border border-neutral-200 flex-col items-center md:flex-row md:justify-between md:items-center`} | |
> | |
<div | |
className={`flex md:flex-[1] h-[fit-content] md:p-4 md:justify-between md:flex-row | |
`} | |
> | |
{selectedImage ? ( | |
<div className="md:max-w-[200px]"> | |
<img | |
src={URL.createObjectURL(selectedImage)} | |
alt="Selected" | |
/> | |
</div> | |
) : ( | |
<div className="inline-flex items-center justify-between"> | |
<div className="p-3 bg-slate-200 justify-center items-center flex"> | |
<BsImages size={56} /> | |
</div> | |
</div> | |
)} | |
</div> | |
<FormField | |
control={form.control} | |
name="adImage" | |
render={({ field }) => ( | |
<FormItem> | |
<FormControl> | |
<Button size="lg" type="button"> | |
<input | |
type="file" | |
className="hidden" | |
id="fileInput" | |
accept="image/*" | |
onBlur={field.onBlur} | |
name={field.name} | |
onChange={(e) => { | |
field.onChange(e.target.files); | |
setSelectedImage(e.target.files?.[0] || null); | |
}} | |
ref={field.ref} | |
/> | |
<label | |
htmlFor="fileInput" | |
className="bg-blue-500 hover:bg-blue-600 text-neutral-90 rounded-md cursor-pointer inline-flex items-center" | |
> | |
<BsPaperclip /> | |
<span className="whitespace-nowrap"> | |
choose your image | |
</span> | |
</label> | |
</Button> | |
</FormControl> | |
{/* <FormDescription>This is your public display email.</FormDescription> */} | |
<FormMessage /> | |
</FormItem> | |
)} | |
/> | |
</div> | |
</div> | |
</div> | |
<div className={cn("flex w-[100%] gap-4 justify-end")}> | |
<div className="space-y-2"> | |
<Button className="gap-1 py-4 px-4" type="submit"> | |
<span>SUBMIT</span> | |
<IoSendOutline /> | |
</Button> | |
</div> | |
</div> | |
</form> | |
</Form> | |
</main> | |
); | |
} |
Thank you so much!
Thanks for sharing!
Thank you so much!
i'm pleased that it helped!
thank you <3
Thanks for sharing this. However, when I pass ref to the input, the client runs validation automatically but removing the ref works perfect. Any idea what's going on here?
Thanks for sharing this. However, when I pass ref to the input, the client runs validation automatically but removing the ref works perfect. Any idea what's going on here?
R: in the new version the Form are passing automatically the ref for the children of the Form item, I got a similar error recently but with a map component form leaflet and got the ref error indicating the component don't have a forwardRef HOC configured
Thank you!
However, if I want to check if the file is uploaded in the first, the resolved error message would be "Max document size is 10MB." instead of "Document is required.".
Here's the code I'm using:
document: z
.any()
.refine(
(files) => !files || files?.length === 0,
"Document is required."
)
.refine((files) => {
return files?.[0]?.size <= MAX_DOCUMENT_FILE_SIZE;
}, `Max document size is 10MB.`)
.refine(
(files) => ACCEPTED_DOCUMENT_MIME_TYPES.includes(files?.[0]?.type),
"Only .pdf format is supported."
),
Thank you!
However, if I want to check if the file is uploaded in the first, the resolved error message would be "Max document size is 10MB." instead of "Document is required.".
Here's the code I'm using:
document: z .any() .refine( (files) => !files || files?.length === 0, "Document is required." ) .refine((files) => { return files?.[0]?.size <= MAX_DOCUMENT_FILE_SIZE; }, `Max document size is 10MB.`) .refine( (files) => ACCEPTED_DOCUMENT_MIME_TYPES.includes(files?.[0]?.type), "Only .pdf format is supported." ),
What happens when you select a file that exceeds the maximum size limit and is not of the allowed type? Is the validation configured appropriately to handle both scenarios, ensuring that "Max document size is 10MB" error message is returned when the uploaded file exceeds the size limit, and "Document is required" message is returned if no file is uploaded?
code:-
"use client";
import { DesktopFooter, MobileFooter } from '@/components/Footer'
import { DesktopNav, MobileNav } from '@/components/Nav'
import { useAuth } from "@/providers/auth";
import React, { useState } from 'react'
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { any, z } from "zod"
import { Button } from "@/components/ui/button"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
const formSchema = z.object({
productName: z.string().min(4, {
message: "Product Name must be at least 4 characters.",
}),
productDescription: z.string().min(6, {
message: "Description of the Product must be at least 6 characters.",
}).optional(),
productImage: z
.any().optional()
// To not allow files other than images
// .refine((files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type), {
// message: '.jpg, .jpeg, .png and .webp files are accepted.',
// })
// To not allow files larger than 5MB
// .refine((files) => files?.[0]?.size <= 5000000, {
// message: Max file size is 5MB.
,
// }),
})
export function ProductRequest() {
const [imageState, setImageState] = useState(any);
// function handleImage() {
// // if (event.target.files) {
// // setImagesState(event.target.files[0]);
// // }
// // else {
// // setImagesState(null);
// // }
// console.log('working')
// }
const form = useForm<z.infer>({
resolver: zodResolver(formSchema),
defaultValues: {
productName: "",
productDescription: "",
productImage: undefined
},
})
// 2. Define a submit handler.
function onSubmit(values: z.infer) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values)
}
return (
<Form {...form}>
<FormField
control={form.control}
name="productName"
render={({ field }) => (
Product Name
<Input placeholder="Name of the Product" {...field} />
)}
/>
<FormField
control={form.control}
name="productDescription"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Input placeholder="Description of the Product" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="productImage"
render={({ field }) => (
<FormItem>
<FormLabel>Image (Optional)</FormLabel>
<FormControl>
<Input type="file" accept='image/*' {...field} onChange={(e) => {
field.onChange(e.target.files);
setImageState(e.target.files?.[0] || null);
}} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
</div>
)
}
const page = () => {
return (
)
}
export default page
I couldn't get this to work with.. I don't understand what it is that I am doing wrong.
code:-
"use client";
import { DesktopFooter, MobileFooter } from '@/components/Footer' import { DesktopNav, MobileNav } from '@/components/Nav' import { useAuth } from "@/providers/auth"; import React, { useState } from 'react'
import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { any, z } from "zod"
import { Button } from "@/components/ui/button" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input"
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"]; const formSchema = z.object({ productName: z.string().min(4, { message: "Product Name must be at least 4 characters.", }), productDescription: z.string().min(6, { message: "Description of the Product must be at least 6 characters.", }).optional(), productImage: z .any().optional() // To not allow files other than images // .refine((files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type), { // message: '.jpg, .jpeg, .png and .webp files are accepted.', // }) // To not allow files larger than 5MB // .refine((files) => files?.[0]?.size <= 5000000, { // message:
Max file size is 5MB.
, // }), })export function ProductRequest() {
const [imageState, setImageState] = useState(any);
// function handleImage() { // // if (event.target.files) { // // setImagesState(event.target.files[0]); // // } // // else { // // setImagesState(null); // // } // console.log('working')
// }
const form = useForm<z.infer>({ resolver: zodResolver(formSchema), defaultValues: { productName: "", productDescription: "", productImage: undefined }, })
// 2. Define a submit handler. function onSubmit(values: z.infer) { // Do something with the form values. // ✅ This will be type-safe and validated. console.log(values) }
return (
<FormField
control={form.control}
name="productName"
render={({ field }) => (Product Name
<Input placeholder="Name of the Product" {...field} />
)} /> <FormField control={form.control} name="productDescription" render={({ field }) => ( <FormItem> <FormLabel>Description</FormLabel> <FormControl> <Input placeholder="Description of the Product" {...field} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="productImage" render={({ field }) => ( <FormItem> <FormLabel>Image (Optional)</FormLabel> <FormControl> <Input type="file" accept='image/*' {...field} onChange={(e) => { field.onChange(e.target.files); setImageState(e.target.files?.[0] || null); }} /> </FormControl> <FormMessage /> </FormItem> )} /> <Button type="submit">Submit</Button> </form> </Form> </div>
) }
const page = () => { return (
)
}
export default pageI couldn't get this to work with.. I don't understand what it is that I am doing wrong.
I was able fix this issue by changing
const [imageState, setImageState]=useState(any)
to
const [imageState, setImageState]=useState<File | null>(null)
BUT
Now I am facing a runtime issue while uploading the image.
I would appreciate any help.
I'm not sure what's wrong with your code. It looks perfect based on the snippet you shared. Perhaps the only difference is the infer part in useForm. Here's the code I shared, with some changes like the type you mentioned:
"use client";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"; //shadcn ui folder
import { cn } from "@/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { BsImages, BsPaperclip } from "react-icons/bs";
import { IoSendOutline } from "react-icons/io5";
import * as z from "zod";
const MAX_FILE_SIZE = 1024 * 1024 * 5;
const ACCEPTED_IMAGE_MIME_TYPES = [
"image/jpeg",
"image/jpg",
"image/png",
"image/webp",
];
const ACCEPTED_IMAGE_TYPES = ["jpeg", "jpg", "png", "webp"];
const formSchema = z.object({
adImage: z
.any()
.refine((files) => {
return files?.[0]?.size <= MAX_FILE_SIZE;
}, `Max image size is 5MB.`)
.refine(
(files) => ACCEPTED_IMAGE_MIME_TYPES.includes(files?.[0]?.type),
"Only .jpg, .jpeg, .png and .webp formats are supported."
),
});
export type ContactFormData = z.infer<typeof formSchema>;
export default function Home() {
const [selectedImage, setSelectedImage] = useState<File | null>(null);
const form = useForm<ContactFormData>({
resolver: zodResolver(formSchema),
defaultValues: {
adImage: undefined,
},
});
const onSubmit = async (data: ContactFormData) => {
console.log(data);
};
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className={cn("flex md:flex-row w-[100%] gap-4 flex-col")}>
<div className="flex w-[100%] gap-4 flex-col ">
<FormLabel>your form title</FormLabel>
<div
className={`flex w-[100%] gap-4 p-4 rounded border border-neutral-200 flex-col items-center md:flex-row md:justify-between md:items-center`}
>
<div
className={`flex md:flex-[1] h-[fit-content] md:p-4 md:justify-between md:flex-row
`}
>
{selectedImage ? (
<div className="md:max-w-[200px]">
<img
src={URL.createObjectURL(selectedImage)}
alt="Selected"
/>
</div>
) : (
<div className="inline-flex items-center justify-between">
<div className="p-3 bg-slate-200 justify-center items-center flex">
<BsImages size={56} />
</div>
</div>
)}
</div>
<FormField
control={form.control}
name="adImage"
render={({ field }) => (
<FormItem>
<FormControl>
<Button size="lg" type="button">
<input
type="file"
className="hidden"
id="fileInput"
accept="image/*"
onBlur={field.onBlur}
name={field.name}
onChange={(e) => {
field.onChange(e.target.files);
setSelectedImage(e.target.files?.[0] || null);
}}
ref={field.ref}
/>
<label
htmlFor="fileInput"
className="bg-blue-500 hover:bg-blue-600 text-neutral-90 rounded-md cursor-pointer inline-flex items-center"
>
<BsPaperclip />
<span className="whitespace-nowrap">
choose your image
</span>
</label>
</Button>
</FormControl>
{/* <FormDescription>This is your public display email.</FormDescription> */}
<FormMessage />
</FormItem>
)}
/>
</div>
</div>
</div>
<div className={cn("flex w-[100%] gap-4 justify-end")}>
<div className="space-y-2">
<Button className="gap-1 py-4 px-4" type="submit">
<span>SUBMIT</span>
<IoSendOutline />
</Button>
</div>
</div>
</form>
</Form>
</main>
);
}
code:-
"use client";
import { DesktopFooter, MobileFooter } from '@/components/Footer' import { DesktopNav, MobileNav } from '@/components/Nav' import { useAuth } from "@/providers/auth"; import React, { useState } from 'react'
import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { any, z } from "zod"
import { Button } from "@/components/ui/button" import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input"
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"]; const formSchema = z.object({ productName: z.string().min(4, { message: "Product Name must be at least 4 characters.", }), productDescription: z.string().min(6, { message: "Description of the Product must be at least 6 characters.", }).optional(), productImage: z .any().optional() // To not allow files other than images // .refine((files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type), { // message: '.jpg, .jpeg, .png and .webp files are accepted.', // }) // To not allow files larger than 5MB // .refine((files) => files?.[0]?.size <= 5000000, { // message:Max file size is 5MB.
, // }), })
export function ProductRequest() {
const [imageState, setImageState] = useState(any);
// function handleImage() { // // if (event.target.files) { // // setImagesState(event.target.files[0]); // // } // // else { // // setImagesState(null); // // } // console.log('working')
// }
const form = useForm<z.infer>({ resolver: zodResolver(formSchema), defaultValues: { productName: "", productDescription: "", productImage: undefined }, })
// 2. Define a submit handler. function onSubmit(values: z.infer) { // Do something with the form values. // ✅ This will be type-safe and validated. console.log(values) }
return (<FormField
control={form.control}
name="productName"
render={({ field }) => (
Product Name
<Input placeholder="Name of the Product" {...field} />)} /> <FormField control={form.control} name="productDescription" render={({ field }) => ( <FormItem> <FormLabel>Description</FormLabel> <FormControl> <Input placeholder="Description of the Product" {...field} /> </FormControl> <FormMessage /> </FormItem> )} /> <FormField control={form.control} name="productImage" render={({ field }) => ( <FormItem> <FormLabel>Image (Optional)</FormLabel> <FormControl> <Input type="file" accept='image/*' {...field} onChange={(e) => { field.onChange(e.target.files); setImageState(e.target.files?.[0] || null); }} /> </FormControl> <FormMessage /> </FormItem> )} /> <Button type="submit">Submit</Button> </form> </Form> </div>
) }
const page = () => { return (
)
}
export default page
I couldn't get this to work with.. I don't understand what it is that I am doing wrong.I was able fix this issue by changing
const [imageState, setImageState]=useState(any)
to
const [imageState, setImageState]=useState<File | null>(null)
BUT
Now I am facing a runtime issue while uploading the image.
I would appreciate any help.
Thank you!
However, if I want to check if the file is uploaded in the first, the resolved error message would be "Max document size is 10MB." instead of "Document is required.".
Here's the code I'm using:
document: z .any() .refine( (files) => !files || files?.length === 0, "Document is required." ) .refine((files) => { return files?.[0]?.size <= MAX_DOCUMENT_FILE_SIZE; }, `Max document size is 10MB.`) .refine( (files) => ACCEPTED_DOCUMENT_MIME_TYPES.includes(files?.[0]?.type), "Only .pdf format is supported." ),
another approach you could use is to set a specific error message like in the z.any({inside here image below
})
where you can setup a message for required and one for invalide_type_error
or use a errorMap where you are able to manipulate others types of errors
Thanks!!!
I'm not sure what's wrong with your code. It looks perfect based on the snippet you shared. Perhaps the only difference is the infer part in useForm. Here's the code I shared, with some changes like the type you mentioned:
"use client"; import { Button } from "@/components/ui/button"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; //shadcn ui folder import { cn } from "@/lib/utils"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { BsImages, BsPaperclip } from "react-icons/bs"; import { IoSendOutline } from "react-icons/io5"; import * as z from "zod"; const MAX_FILE_SIZE = 1024 * 1024 * 5; const ACCEPTED_IMAGE_MIME_TYPES = [ "image/jpeg", "image/jpg", "image/png", "image/webp", ]; const ACCEPTED_IMAGE_TYPES = ["jpeg", "jpg", "png", "webp"]; const formSchema = z.object({ adImage: z .any() .refine((files) => { return files?.[0]?.size <= MAX_FILE_SIZE; }, `Max image size is 5MB.`) .refine( (files) => ACCEPTED_IMAGE_MIME_TYPES.includes(files?.[0]?.type), "Only .jpg, .jpeg, .png and .webp formats are supported." ), }); export type ContactFormData = z.infer<typeof formSchema>; export default function Home() { const [selectedImage, setSelectedImage] = useState<File | null>(null); const form = useForm<ContactFormData>({ resolver: zodResolver(formSchema), defaultValues: { adImage: undefined, }, }); const onSubmit = async (data: ContactFormData) => { console.log(data); }; return ( <main className="flex min-h-screen flex-col items-center justify-between p-24"> <Form {...form}> <form onSubmit={form.handleSubmit(onSubmit)}> <div className={cn("flex md:flex-row w-[100%] gap-4 flex-col")}> <div className="flex w-[100%] gap-4 flex-col "> <FormLabel>your form title</FormLabel> <div className={`flex w-[100%] gap-4 p-4 rounded border border-neutral-200 flex-col items-center md:flex-row md:justify-between md:items-center`} > <div className={`flex md:flex-[1] h-[fit-content] md:p-4 md:justify-between md:flex-row `} > {selectedImage ? ( <div className="md:max-w-[200px]"> <img src={URL.createObjectURL(selectedImage)} alt="Selected" /> </div> ) : ( <div className="inline-flex items-center justify-between"> <div className="p-3 bg-slate-200 justify-center items-center flex"> <BsImages size={56} /> </div> </div> )} </div> <FormField control={form.control} name="adImage" render={({ field }) => ( <FormItem> <FormControl> <Button size="lg" type="button"> <input type="file" className="hidden" id="fileInput" accept="image/*" onBlur={field.onBlur} name={field.name} onChange={(e) => { field.onChange(e.target.files); setSelectedImage(e.target.files?.[0] || null); }} ref={field.ref} /> <label htmlFor="fileInput" className="bg-blue-500 hover:bg-blue-600 text-neutral-90 rounded-md cursor-pointer inline-flex items-center" > <BsPaperclip /> <span className="whitespace-nowrap"> choose your image </span> </label> </Button> </FormControl> {/* <FormDescription>This is your public display email.</FormDescription> */} <FormMessage /> </FormItem> )} /> </div> </div> </div> <div className={cn("flex w-[100%] gap-4 justify-end")}> <div className="space-y-2"> <Button className="gap-1 py-4 px-4" type="submit"> <span>SUBMIT</span> <IoSendOutline /> </Button> </div> </div> </form> </Form> </main> ); }code:-
"use client";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useState } from 'react';
import { useForm } from "react-hook-form";
import { any, z } from "zod";
const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp"]; const formSchema = z.object({ productName: z.string().min(4, { message: "Product Name must be at least 4 characters.", }), productDescription: z.string().min(6, { message: "Description of the Product must be at least 6 characters.", }).optional(), productImage: z .any().optional() // To not allow files other than images // .refine((files) => ACCEPTED_IMAGE_TYPES.includes(files?.[0]?.type), { // message: '.jpg, .jpeg, .png and .webp files are accepted.', // }) // To not allow files larger than 5MB // .refine((files) => files?.[0]?.size <= 5000000, { // message: `Max file size is 5MB.`, // }), })
export function ProductRequest() {
const [imageState, setImageState] = useState(any);
// function handleImage() { // // if (event.target.files) { // // setImagesState(event.target.files[0]); // // } // // else { // // setImagesState(null); // // } // console.log('working')
// }
const form = useForm<z.infer>({ resolver: zodResolver(formSchema), defaultValues: { productName: "", productDescription: "", productImage: undefined }, })
// 2. Define a submit handler. function onSubmit(values: z.infer) { // Do something with the form values. // ✅ This will be type-safe and validated. console.log(values) }
return (
<FormField
control={form.control}
name="productName"
render={({ field }) => (
Product Name
<Input placeholder="Name of the Product" {...field} />
)}
/>
<FormField
control={form.control}
name="productDescription"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Input placeholder="Description of the Product" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="productImage"
render={({ field }) => (
<FormItem>
<FormLabel>Image (Optional)</FormLabel>
<FormControl>
<Input type="file" accept='image/*' {...field} onChange={(e) => {
field.onChange(e.target.files);
setImageState(e.target.files?.[0] || null);
}} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
</div>
) }
const page = () => { return (
)
}
export default page
I couldn't get this to work with.. I don't understand what it is that I am doing wrong.
I was able fix this issue by changing
const [imageState, setImageState]=useState(any)
toconst [imageState, setImageState]=useState<File | null>(null)
BUT
Now I am facing a runtime issue while uploading the image.
I would appreciate any help.
Thankyou,,! Although it didn't work.. I was constantly running into errors.. so I have to hand it over to a senior dev
@rudy128
i tried to edit you code to a better reading but it did not work well,
all images you shared are private and i couldn't see any of then
can you share they again?
most of the difference i see in your code was this piece
const form = useForm<z.infer>({ resolver: zodResolver(formSchema), defaultValues: { productName: "", productDescription: "", productImage: undefined }, })
where you may received a error of "you're using a function/value as type" or something similar to it
Thank you!
However, if I want to check if the file is uploaded in the first, the resolved error message would be "Max document size is 10MB." instead of "Document is required.".
Here's the code I'm using:
document: z .any() .refine( (files) => !files || files?.length === 0, "Document is required." ) .refine((files) => { return files?.[0]?.size <= MAX_DOCUMENT_FILE_SIZE; }, `Max document size is 10MB.`) .refine( (files) => ACCEPTED_DOCUMENT_MIME_TYPES.includes(files?.[0]?.type), "Only .pdf format is supported." ),
here is for file required
.refine((files) => files?.length !== 0, 'Document is required')
Thanks for sharing!