Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

React.js react-dropzone Drag and Drop Multiple Files With Preview Example With Validation in Javascript

Posted on February 15, 2023

 

 

Welcome folks today in this blog post we will be using the react-dropzone library to drag and drop multiple files with preview example and validation in browser using javascript. All the full source code of the application is shown below.

 

 

Get Started

 

 

In order to get started you need to make a new react.js project using the below command as shown below

 

 

npx create-react-app sampleapp

 

 

cd sampleapp

 

 

npm i react-dropzone

 

 

And after that you will see the below directory structure of the react.js app as shown below

 

 

 

 

Drag and Drop Multiple Files Upload

 

 

Now we need to modify the App.js file and copy paste the following code

 

 

App.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React from 'react';
import {useDropzone} from 'react-dropzone';
 
 
export default function App() {
  const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
  
  const files = acceptedFiles.map(file => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
    </li>
  ));
 
  return (
    <section className="container">
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <aside>
        <h4>Files</h4>
        <ul>{files}</ul>
      </aside>
    </section>
  );
}

 

 

As you can see we are importing the react-dropzone library and then we are rendering the drag and drop widget inside the browser and the user can drag the files which needs to be uploaded. And then we are showing the file size and the path as shown below

 

 

 

 

 

Accepting Only Certain Files

 

 

Now we can pass a config object to the react dropzone and here we can accept only specific file extension which is png and html as shown below

 

 

JavaScript
1
2
3
4
5
6
useDropzone({
    accept: {
      'image/png': ['.png'],
      'text/html': ['.html', '.htm'],
    }
});

 

 

Validating the Max File Size and No of Files

 

 

You can even control how many max files you can select for uploading and also you can control the maximum size of the file to upload as shown below

 

 

JavaScript
1
2
3
4
5
6
7
8
useDropzone({
    accept: {
      'image/png': ['.png'],
      'text/html': ['.html', '.htm'],
    },
    maxFiles:3,
    maxSize:500000
});

 

 

Custom Validation Message

 

 

Now we can even pass a custom validation message to the react-dropzone by using the validator property as shown below

 

 

App.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import React from 'react';
import {useDropzone} from 'react-dropzone';
 
const maxLength = 5;
 
function nameLengthValidator(file) {
  if (file.name.length > maxLength) {
    return {
      code: "name-too-large",
      message: `Name is larger than ${maxLength} characters`
    };
  }
 
  return null
}
 
export default function App(props) {
  const {
    acceptedFiles,
    fileRejections,
    getRootProps,
    getInputProps
  } = useDropzone({
    validator: nameLengthValidator
  });
 
  const acceptedFileItems = acceptedFiles.map(file => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
    </li>
  ));
 
  const fileRejectionItems = fileRejections.map(({ file, errors }) => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
      <ul>
        {errors.map(e => (
          <li key={e.code}>{e.message}</li>
        ))}
      </ul>
    </li>
  ));
 
  return (
    <section className="container">
      <div {...getRootProps({ className: 'dropzone' })}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
        <em>(Only files with name less than 20 characters will be accepted)</em>
      </div>
      <aside>
        <h4>Accepted files</h4>
        <ul>{acceptedFileItems}</ul>
        <h4>Rejected files</h4>
        <ul>{fileRejectionItems}</ul>
      </aside>
    </section>
  );
}

 

 

As you can see we are defining the custom validator function in which we are checking the name of the file and we are checking the length of the file. And we have given the maxLength for the characters is 5. And then we are showing the error message if the name of the file is larger than 5 as shown below

 

 

 

 

 

Open File Dialog on Button Click

 

 

Now we will be opening file dialog on button click in react.js using the react-dropzone library as shown below

 

 

App.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import React from 'react';
import {useDropzone} from 'react-dropzone';
 
export default function App(props) {
  const {getRootProps, getInputProps, open, acceptedFiles} = useDropzone({
    // Disable click and keydown behavior
    noClick: true,
    noKeyboard: true
  });
 
  const files = acceptedFiles.map(file => (
    <li key={file.path}>
      {file.path} - {file.size} bytes
    </li>
  ));
 
  return (
    <div className="container">
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here</p>
        <button type="button" onClick={open}>
          Open File Dialog
        </button>
      </div>
      <aside>
        <h4>Files</h4>
        <ul>{files}</ul>
      </aside>
    </div>
  );
}

 

 

As you can see we are having a button and inside this we are attaching the onClick attribute where we are executing the open() method and inside it we are passing the onclick and onkeyboard boolean attribute to true.

 

 

 

 

 

Showing Preview of Images

 

 

Now we can also see the live preview of the files that you select using the react-dropzone library as shown below

 

 

App.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import React, {useEffect, useState} from 'react';
import {useDropzone} from 'react-dropzone';
 
const thumbsContainer = {
  display: 'flex',
  flexDirection: 'row',
  flexWrap: 'wrap',
  marginTop: 16
};
 
const thumb = {
  display: 'inline-flex',
  borderRadius: 2,
  border: '1px solid #eaeaea',
  marginBottom: 8,
  marginRight: 8,
  width: 100,
  height: 100,
  padding: 4,
  boxSizing: 'border-box'
};
 
const thumbInner = {
  display: 'flex',
  minWidth: 0,
  overflow: 'hidden'
};
 
const img = {
  display: 'block',
  width: 'auto',
  height: '100%'
};
 
export default function App(props) {
  const [files, setFiles] = useState([]);
  const {getRootProps, getInputProps} = useDropzone({
    accept: {
      'image/*': []
    },
    onDrop: acceptedFiles => {
      setFiles(acceptedFiles.map(file => Object.assign(file, {
        preview: URL.createObjectURL(file)
      })));
    }
  });
  
  const thumbs = files.map(file => (
    <div style={thumb} key={file.name}>
      <div style={thumbInner}>
        <img
          src={file.preview}
          style={img}
          // Revoke data uri after image is loaded
          onLoad={() => { URL.revokeObjectURL(file.preview) }}
        />
      </div>
    </div>
  ));
 
  useEffect(() => {
    // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
    return () => files.forEach(file => URL.revokeObjectURL(file.preview));
  }, []);
 
  return (
    <section className="container">
      <div {...getRootProps({className: 'dropzone'})}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>
      <aside style={thumbsContainer}>
        {thumbs}
      </aside>
    </section>
  );
}

 

 

 

Recent Posts

  • Node.js Express Server Side Form Validation With Custom Error Messages Using express-validator Library in Javascript
  • Node.js Express Project to Validate User Form Data Using joi Schema Validation Library Full Example
  • Node.js Puppeteer Project to Export Handlebars Resume Template to PDF Document in Express Using Javascript
  • Node.js Express Passwordless Login Example to Send Magic Auth Link Using Nodemailer
  • Python 3 Tkinter Script to Encrypt PDF Documents With Password Using PyPDF2 Library GUI Desktop App
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme