stormy-gold
stormy-gold11mo ago

Dragger on drop = false still calling api on drag

dragger is calling api when there is no action
11 Replies
kapa.ai
kapa.ai11mo ago
Hi @parothia. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The Upload.Dragger component from Ant Design, which is used in Refine, calls an API when a file is dropped into the area. This is specified by the action prop in the Upload.Dragger component. For example, in the code snippet from the Refine documentation (https://refine.dev/docs/advanced-tutorials/upload/multipart-upload/), the action prop is set to `${apiUrl}/media/upload`, which means the file will be uploaded to this URL when it's dropped into the Upload.Dragger area.
<Upload.Dragger
name="file"
action={`${apiUrl}/media/upload`}
listType="picture"
maxCount={5}
multiple
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
<Upload.Dragger
name="file"
action={`${apiUrl}/media/upload`}
listType="picture"
maxCount={5}
multiple
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
If you don't want the Upload.Dragger to automatically call an API, you can use the customRequest prop to customize the upload behavior. This prop accepts a function that will be called when a file is dropped. You can define your own logic inside this function. For example, in the code snippet from the Refine blog (https://refine.dev/blog/simple-web-application-with-refine/), the customRequest prop is used to upload the file to a Supabase storage bucket.
<Upload.Dragger
name="file"
listType="picture"
multiple
customRequest={async ({
file,
onError,
onSuccess,
}) => {
// Custom upload logic here
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
<Upload.Dragger
name="file"
listType="picture"
multiple
customRequest={async ({
file,
onError,
onSuccess,
}) => {
// Custom upload logic here
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
In this case, the Upload.Dragger will not automatically call an API when a file is dropped. Instead, it will execute the function provided to the customRequest prop. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@1149386202403844156> kapa.ai is still learning and improving, please let us know how it did by reacting below
stormy-gold
stormy-gold11mo ago
@kapa.ai only one file should be uploaded at a time..and it show loading
kapa.ai
kapa.ai11mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To allow only one file to be uploaded at a time, you can set the multiple prop of the Upload.Dragger component to false. This will restrict the file selection to a single file at a time. To show a loading state while the file is being uploaded, you can use the useFileUploadState hook provided by Refine. This hook returns an isLoading state that you can use to show a loading spinner or disable the form's "Save" button. Here's an example based on the code snippets from the Refine documentation (https://refine.dev/docs/advanced-tutorials/upload/multipart-upload/):
import { useApiUrl } from "@refinedev/core";
import {
getValueFromEvent,
useFileUploadState,
Create,
useForm,
} from "@refinedev/antd";
import { Upload, Form, Input } from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();

const { isLoading, onChange } = useFileUploadState();

const apiUrl = useApiUrl();

return (
<Create
saveButtonProps={{
...saveButtonProps,
disabled: isLoading,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item
name="image"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
>
<Upload.Dragger
name="file"
action={`${apiUrl}/media/upload`}
listType="picture"
maxCount={1}
onChange={onChange}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
import { useApiUrl } from "@refinedev/core";
import {
getValueFromEvent,
useFileUploadState,
Create,
useForm,
} from "@refinedev/antd";
import { Upload, Form, Input } from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();

const { isLoading, onChange } = useFileUploadState();

const apiUrl = useApiUrl();

return (
<Create
saveButtonProps={{
...saveButtonProps,
disabled: isLoading,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item
name="image"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
>
<Upload.Dragger
name="file"
action={`${apiUrl}/media/upload`}
listType="picture"
maxCount={1}
onChange={onChange}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
In this example, the maxCount prop is set to 1 to allow only one file to be uploaded. The isLoading state from the useFileUploadState hook is used to disable the "Save" button while the file is being uploaded. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@1149386202403844156> kapa.ai is still learning and improving, please let us know how it did by reacting below
stormy-gold
stormy-gold11mo ago
@kapa.ai can u fix this code..this should not call api on drag
kapa.ai
kapa.ai11mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Sure, to prevent the Upload.Dragger from automatically calling an API on drag, you can remove the action prop and use the customRequest prop to handle the file upload manually. Here's how you can modify your code:
import {
useApiUrl,
} from "@refinedev/core";
import {
getValueFromEvent,
Create,
useForm,
} from "@refinedev/antd";
import {
Upload,
Form,
Input,
} from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();

const { isLoading, onChange } = useFileUploadState();

return (
<Create
saveButtonProps={{
...saveButtonProps,
disabled: isLoading,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item
name="image"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
>
<Upload.Dragger
name="file"
listType="picture"
maxCount={1}
multiple={false}
onChange={onChange}
customRequest={({ file, onSuccess }) => {
// Handle file upload manually here
// Call onSuccess when upload is done
onSuccess({ response: "Server Response" });
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
import {
useApiUrl,
} from "@refinedev/core";
import {
getValueFromEvent,
Create,
useForm,
} from "@refinedev/antd";
import {
Upload,
Form,
Input,
} from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();

const { isLoading, onChange } = useFileUploadState();

return (
<Create
saveButtonProps={{
...saveButtonProps,
disabled: isLoading,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item
name="image"
valuePropName="fileList"
getValueFromEvent={getValueFromEvent}
noStyle
>
<Upload.Dragger
name="file"
listType="picture"
maxCount={1}
multiple={false}
onChange={onChange}
customRequest={({ file, onSuccess }) => {
// Handle file upload manually here
// Call onSuccess when upload is done
onSuccess({ response: "Server Response" });
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
In this code, the customRequest prop is used to handle the file upload manually. The onSuccess function is called when the upload is done. You can replace the comment // Handle file upload manually here with your own logic to upload the file. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@1149386202403844156> kapa.ai is still learning and improving, please let us know how it did by reacting below
stormy-gold
stormy-gold11mo ago
@kapa.ai call the api on create button not on file drag
kapa.ai
kapa.ai11mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To call the API on the "Create" button click instead of on file drag, you can store the file in a local state when it's dragged and then upload it when the "Create" button is clicked. Here's how you can modify your code:
import { useState } from "react";
import { Create, useForm } from "@refinedev/antd";
import { Upload, Form, Input } from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();
const [file, setFile] = useState<File | null>(null);

const handleFileChange = ({ file }: any) => {
setFile(file);
};

const handleFinish = async (values: any) => {
if (file) {
// Upload the file here
}

// Call the original onFinish function
saveButtonProps.onFinish(values);
};

return (
<Create
saveButtonProps={{
...saveButtonProps,
onFinish: handleFinish,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item name="image" valuePropName="fileList" noStyle>
<Upload.Dragger
name="file"
listType="picture"
maxCount={1}
multiple={false}
onChange={handleFileChange}
customRequest={({ onSuccess }) => {
// Call onSuccess immediately to prevent the upload from hanging
onSuccess("ok");
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
import { useState } from "react";
import { Create, useForm } from "@refinedev/antd";
import { Upload, Form, Input } from "antd";

export const PostCreate: React.FC = () => {
const { formProps, saveButtonProps } = useForm<IPost>();
const [file, setFile] = useState<File | null>(null);

const handleFileChange = ({ file }: any) => {
setFile(file);
};

const handleFinish = async (values: any) => {
if (file) {
// Upload the file here
}

// Call the original onFinish function
saveButtonProps.onFinish(values);
};

return (
<Create
saveButtonProps={{
...saveButtonProps,
onFinish: handleFinish,
}}
>
<Form {...formProps} layout="vertical">
<Form.Item
label="Title"
name="title"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item label="Image">
<Form.Item name="image" valuePropName="fileList" noStyle>
<Upload.Dragger
name="file"
listType="picture"
maxCount={1}
multiple={false}
onChange={handleFileChange}
customRequest={({ onSuccess }) => {
// Call onSuccess immediately to prevent the upload from hanging
onSuccess("ok");
}}
>
<p className="ant-upload-text">
Drag & drop a file in this area
</p>
</Upload.Dragger>
</Form.Item>
</Form.Item>
</Form>
</Create>
);
};
In this code, the handleFileChange function is called when a file is dragged into the Upload.Dragger area. This function stores the file in a local state. The handleFinish function is called when the "Create" button is clicked. This function uploads the file and then calls the original onFinish function. The customRequest prop is used to prevent the Upload.Dragger from automatically uploading the file. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai11mo ago
<@1149386202403844156> kapa.ai is still learning and improving, please let us know how it did by reacting below