using useForm from @refinedev/core how can I let the user upload a file.

using useForm from @refinedev/core how can I let the user upload a file.
5 Replies
kapa.ai
kapa.ai4w ago
Hi @Todilo. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To allow users to upload a file using useForm from @refinedev/core, you can implement file upload functionality in your form. Here's how you can do it: 1. First, you'll need to use the useForm hook from @refinedev/core along with other necessary imports. 2. Then, you can create a form that includes a file input field. 3. You'll need to handle the file upload process, which typically involves converting the file to Base64 or using a multipart form data approach. Here's an example of how you can implement file upload using Base64 encoding:
import {
file2Base64,
} from "@refinedev/core";

import {
Create,
useForm,
getValueFromEvent,
} from "@refinedev/antd";
import { Form, Upload, Input } from "antd";

export const UserCreate: React.FC = () => {
const { form, formProps, saveButtonProps } = useForm<IUser>();

return (
<Create saveButtonProps={saveButtonProps}>
<Form
{...formProps}
layout="vertical"
onFinish={async (values) => {
const base64Files = [];
// @ts-ignore
const { avatar } = values;

for (const file of avatar) {
if (file.originFileObj) {
const base64String = await file2Base64(file);

base64Files.push({
...file,
base64String,
});
} else {
base64Files.push(file);
}
}

return (
formProps.onFinish &&
formProps.onFinish({
...values,
avatar: base64Files,
})
);
}}
>
<Form.Item
label="First Name"
name="firstName"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Avatar">
<Form.Item
name="avatar"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
rules={[
{
required: true,
},
]}
>
<Upload.Dragger
listType="picture"
multiple
beforeUpload={() => false}
>
<p className="ant-upload-text">Drag & drop a file in this area</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
import {
file2Base64,
} from "@refinedev/core";

import {
Create,
useForm,
getValueFromEvent,
} from "@refinedev/antd";
import { Form, Upload, Input } from "antd";

export const UserCreate: React.FC = () => {
const { form, formProps, saveButtonProps } = useForm<IUser>();

return (
<Create saveButtonProps={saveButtonProps}>
<Form
{...formProps}
layout="vertical"
onFinish={async (values) => {
const base64Files = [];
// @ts-ignore
const { avatar } = values;

for (const file of avatar) {
if (file.originFileObj) {
const base64String = await file2Base64(file);

base64Files.push({
...file,
base64String,
});
} else {
base64Files.push(file);
}
}

return (
formProps.onFinish &&
formProps.onFinish({
...values,
avatar: base64Files,
})
);
}}
>
<Form.Item
label="First Name"
name="firstName"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Avatar">
<Form.Item
name="avatar"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
rules={[
{
required: true,
},
]}
>
<Upload.Dragger
listType="picture"
multiple
beforeUpload={() => false}
>
<p className="ant-upload-text">Drag & drop a file in this area</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
In this example, we're using the file2Base64 function from @refinedev/core to convert the uploaded file to a Base64 string. The getValueFromEvent function is used to properly handle the file input value. You can find more detailed information and examples in the following resources: 1. Base64 Upload Documentation 2. Multipart Upload Documentation These resources provide comprehensive guides on implementing file uploads in refine, including both Base64 and multipart approaches. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@207945811592478720> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
ambitious-aqua
ambitious-aquaOP4w ago
@kapa.ai can I configure the content type to multiplart/form-data
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, you can configure the content type to multipart/form-data when using useForm from @refinedev/core for file uploads. This approach is particularly useful when you need to upload larger files or multiple files at once. Here's how you can implement multipart file upload using refine: 1. First, you'll need to set up your form using useForm from @refinedev/core. 2. Then, you'll use the FormData API to handle the file upload. Here's an example of how you can implement this:
import { useState } from "react";
import { useForm } from "@refinedev/react-hook-form";
import { useSelect, useApiUrl } from "@refinedev/core";

import axios from "axios";

export const PostCreate: React.FC = () => {
const [isUploading, setIsUploading] = useState<boolean>(false);

const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
setValue,
} = useForm();

const apiURL = useApiUrl();

const onSubmitFile = async () => {
setIsUploading(true);
const inputFile = document.getElementById("fileInput") as HTMLInputElement;

const formData = new FormData();
formData.append("file", inputFile?.files?.item(0) as File);

const res = await axios.post<{ url: string }>(
`${apiURL}/media/upload`,
formData,
{
withCredentials: false,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
);

setValue("thumbnail", res.data.url);
setIsUploading(false);
};
return (
<form onSubmit={handleSubmit(onFinish)}>
{/* Other form fields */}
<label>Image: </label>
<input id="fileInput" type="file" onChange={onSubmitFile} />
<input type="hidden" {...register("thumbnail", { required: true })} />
{errors.thumbnail && <span>This field is required</span>}
<br />
<br />
<input type="submit" disabled={isUploading} value="Submit" />
{formLoading && <p>Loading</p>}
</form>
);
};
import { useState } from "react";
import { useForm } from "@refinedev/react-hook-form";
import { useSelect, useApiUrl } from "@refinedev/core";

import axios from "axios";

export const PostCreate: React.FC = () => {
const [isUploading, setIsUploading] = useState<boolean>(false);

const {
refineCore: { onFinish, formLoading },
register,
handleSubmit,
formState: { errors },
setValue,
} = useForm();

const apiURL = useApiUrl();

const onSubmitFile = async () => {
setIsUploading(true);
const inputFile = document.getElementById("fileInput") as HTMLInputElement;

const formData = new FormData();
formData.append("file", inputFile?.files?.item(0) as File);

const res = await axios.post<{ url: string }>(
`${apiURL}/media/upload`,
formData,
{
withCredentials: false,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
);

setValue("thumbnail", res.data.url);
setIsUploading(false);
};
return (
<form onSubmit={handleSubmit(onFinish)}>
{/* Other form fields */}
<label>Image: </label>
<input id="fileInput" type="file" onChange={onSubmitFile} />
<input type="hidden" {...register("thumbnail", { required: true })} />
{errors.thumbnail && <span>This field is required</span>}
<br />
<br />
<input type="submit" disabled={isUploading} value="Submit" />
{formLoading && <p>Loading</p>}
</form>
);
};
In this example: 1. We're using FormData to create a multipart form data object. 2. The file is appended to the FormData object. 3. We're using axios to send a POST request with the FormData object. 4. The content type is automatically set to multipart/form-data when using FormData. This approach allows you to upload files as multipart/form-data, which is efficient for larger files and multiple file uploads. For more detailed information, you can refer to the Multipart Upload Documentation provided by refine. Remember to ensure that your backend is configured to handle multipart form data requests. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@207945811592478720> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?