Hello World
Hello World

Reputation: 154

Antd file upload validation in Reactjs

I am having a file upload using Antd design and it makes the file upload fine.

<Upload {...props}>
  <Button icon={<UploadOutlined />}>Upload png only</Button>
</Upload>

Here I have a beforeUplaod function and its code looks like,

const beforeUpload = (file) => {
  const isPNG = file.type === "image/png";
  if (!isPNG) {
    message.error(`${file.name} is not a png file`);
  }
  // return Upload.LIST_IGNORE; (This will work in newer version but I am using older one which is 4.9.4.
}

As I have mentioned in the above code, if the uploaded image is not png then it will remove the uploaded one from current list as we use Upload.LIST_IGNORE but unfortunately I am working in a older version 4.9.4 and it doesn't have any such keyword to remove the inValid upload from the list.

Could you please kindly help me to remove the uploaded invalid item from the list for version 4.9.4?

Working example:

Edit antd upload component as file selector (forked)

Result:

enter image description here

After some try, I have prevented the file to display in the list if it is not valid but unfortunately the delete of the uploaded file doesn't work now (which was working fine before this current implementation).

Edit antd typescript (forked)

Upvotes: 2

Views: 22615

Answers (2)

Nouman Rafique
Nouman Rafique

Reputation: 849

You can create a state & control the fileList. In new version, we can use Upload.LIST_IGNORE but have a look at the API Section. If you do not want to upload the file, you can simply return false or if you use promise, you can reject with reject(false).

Have a look at beforeUpload in API Section of Upload Component. https://ant.design/components/upload/#API

import { useState } from 'react';
import { Upload, Button, message, UploadProps } from 'antd';
import { UploadOutlined } from '@ant-design/icons';

function App() {
    const [fileList, setFileList] = useState([]);
    const [mode, setMode] = useState(false);

    const uploadProps = {
        multiple: mode,
        fileList,
        beforeUpload: (file, filesArray) => {
            let count = 0;
            let files = filesArray.filter((file) => {
                const isPNG = file.type === 'image/png';
                !isPNG && count++;
                return isPNG;
            });

            if (count > 0) {
                setFileList([]);
                message.error(`${count} Files Not Uploaded. Please Upload PNG File/s`);
                return false;
            }

            // If Mode Is Multiple, Simply Store All Files
            if (mode) {
                setFileList(files);
            } else {
                setFileList((prev) => {
                    let newFiles = [...prev];
                    newFiles.push(file);
                    return newFiles;
                });
            }
            return true;

            // Using Promise
            // return new Promise((resolve, reject) => {
            //  // If Not PNG, Reject The Promise
            //  if (!isPNG) return reject(false);

            //  // Else Set The FileList & Send The File
            //  setFileList([file]);
            //  resolve(file);
            // });
        },
        onRemove: (file) => {
            setFileList((prev) => prev.filter((f) => f.uid !== file.uid));
        }
    };

    console.log(fileList);

    return (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
            <div style={{ marginBottom: '10px' }}>
                <Button type='primary' onClick={() => setMode((prev) => !prev)}>
                    Toggle Mode
                </Button>
            </div>
            <Upload {...uploadProps}>
                <Button icon={<UploadOutlined />}>Upload png only</Button>
            </Upload>
        </div>
    );
}

export default App;

enter image description here

Hope this solve your problem

Upvotes: 1

Drew Reese
Drew Reese

Reputation: 202846

I was able to get the removal of selected/uploaded files by implementing an onRemove handler.

Example:

const Uploader = () => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const validateFileType = (
    { type, name }: UploadFile,
    allowedTypes?: string
  ) => {
    if (!allowedTypes) {
      return true;
    }

    if (type) {
      return allowedTypes.includes(type);
    }
  };

  const uploadProps = useMemo(
    () => ({
      beforeUpload: (file: UploadFile) => {
        const isAllowedType = validateFileType(file, "image/png");
        if (!isAllowedType) {
          setFileList((state) => [...state]);
          message.error(`${file.name} is not PNG file`);
          return false;
        }
        setFileList((state) => [...state, file]);
        return false;
      },
      onRemove: (file: UploadFile) => {
        if (fileList.some((item) => item.uid === file.uid)) {
          setFileList((fileList) =>
            fileList.filter((item) => item.uid !== file.uid)
          );
          return true;
        }
        return false;
      }
    }),
    [fileList]
  );

  return (
    <Upload multiple {...uploadProps} fileList={fileList}>
      <Button icon={<UploadOutlined />}>Upload png only</Button>
    </Upload>
  );
};

Edit antd-file-upload-validation-in-reactjs

Upvotes: 2

Related Questions