How to create a drag-and-drop file uploader web page using JavaScript ?

Published: September 03, 2024

Tags: Javascript;

DMCA.com Protection Status

Introduction

In today's digital world, enhancing user experience is crucial for any web application. One effective way to do this is by implementing a drag-and-drop file uploader using JavaScript. This feature allows users to upload files by simply dragging and dropping them into a designated area, making the process more intuitive and user-friendly. In this guide, we'll walk you through building a drag-and-drop file uploader from scratch, complete with image previews and automatic form submission.

Basic Code drag and drop files

Below, you'll find the basic code structure for creating a drag-and-drop file uploader. At the end of this article, the full code is provided for easy reference.

How to create a drag-and-drop file uploader web page using JavaScript ?
How to create a drag-and-drop file uploader web page using JavaScript ?

HTML Structure

Start by creating a simple HTML structure that includes an input element hidden from view and a container for the drag-and-drop area. This setup will allow you to visually enhance the drag-and-drop interface later on.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drag-and-Drop File Uploader</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <h1>Drag-and-Drop File Uploader</h1>
  <div id="drop-area">Drag file here to upload</div>

  <form id="upload-form" action="/" method="post" enctype="multipart/form-data">
    <input type="file" name="docfile" id="file-selector" multiple hidden>
    <div id="preview-container"></div>
  </form>

  <script src="script.js"></script>
</body>
</html>

CSS Styling

The next step is to add some basic CSS styles to enhance the visual appeal of the drag-and-drop area and the file previews. This helps create a more engaging user interface.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* style.css */
  body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
  }

  h1 {
    text-align: center;
  }

  #drop-area {
    width: 400px;
    height: 200px;
    margin: 20px auto;
    border: 2px dashed #cccccc;
    text-align: center;
    line-height: 200px;
    cursor: pointer;
  }

  #preview-container {
    text-align: center;
  }

JavaScript for Drag-and-Drop

Now, let's dive into the JavaScript code that powers the drag-and-drop functionality. This script handles file dragging, dropping, and previewing, as well as optional automatic form submission.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// script.js
  const dropArea = document.getElementById('drop-area');
  const fileSelector = document.getElementById('file-selector');
  const fileInput = document.getElementById('file-selector');
  const uploadForm = document.getElementById('upload-form');

  function preventDefaults(event) {
    event.preventDefault();
    event.stopPropagation();
  }

  dropArea.addEventListener('dragover', preventDefaults);
  dropArea.addEventListener('dragenter', preventDefaults);
  dropArea.addEventListener('dragleave', preventDefaults);
  dropArea.addEventListener('drop', handleDrop);

  function handleDrop(event) {
    preventDefaults(event);
    const files = event.dataTransfer.files;
    if (files.length) {
      fileInput.files = files;
    }
  }

Additional Features for Enhanced User Experience

Highlighting the Drop Area

A key aspect of a user-friendly drag-and-drop interface is visual feedback during user interactions. For instance, you can change the background color or border style of the drop area when a user drags files over it. This lets users know the drop area is active and ready to accept files.

1
2
3
4
5
6
dropArea.addEventListener('dragover', () => {
   dropArea.classList.add('highlight');
 });
 dropArea.addEventListener('dragleave', () => {
   dropArea.classList.remove('highlight');
 });

And the corresponding CSS:

1
2
3
4
.highlight {
  border-color: #4CAF50;
  background-color: #f0f0f0;
}

Automatic Form Submission

For a seamless user experience, you can configure the form to submit automatically when files are dropped into the area. This eliminates the need for users to manually click a submit button.

1
2
3
function submitFormAutomatically() {
  uploadForm.submit();
}

Finally, integrate the submitFormAutomatically() function into the handleDrop function:

1
2
3
4
5
6
7
8
function handleDrop(event) {
  preventDefaults(event);
  const files = event.dataTransfer.files;
  if (files.length) {
    fileInput.files = files;
    submitFormAutomatically();
  }
}

Creating image preview

Instead of automatic form submission, you might want to provide users with a preview of the files they are about to upload. This is particularly useful for image files.

CSS for Image Previews

1
2
3
4
5
6
7
.preview-image {
    object-fit: cover;
    width: 100px;
    height: 100px;
    margin: 10px;
    border: 1px solid #ddd;
  }

JavaScript for Image Previews

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function previewFiles(files) {
     const previewContainer = document.getElementById('preview-container');
     previewContainer.innerHTML = '';
     Array.from(files).forEach(file => {
       const reader = new FileReader();
       reader.readAsDataURL(file);
       reader.onloadend = function () {
         const img = document.createElement('img');
         img.src = reader.result;
         img.classList.add('preview-image');
         previewContainer.appendChild(img);
       };
     });
   }

Finally, integrate the previewFiles(files) function into the handleDrop function:

1
2
3
4
5
6
7
8
function handleDrop(event) {
    preventDefaults(event);
    const files = event.dataTransfer.files;
    if (files.length) {
      fileInput.files = files;
      previewFiles(files);
    }
  }

Full Code Examples

Below are two complete code examples. The first provides basic drag-and-drop functionality, and the second includes additional features like drop area highlighting and image previews.

Code Example 1: Basic Drag-and-Drop

 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
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drag-and-Drop File Uploader</title>
  <style>
  /* style.css */
  body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
  }

  h1 {
    text-align: center;
  }

  #drop-area {
    width: 400px;
    height: 200px;
    margin: 20px auto;
    border: 2px dashed #cccccc;
    text-align: center;
    line-height: 200px;
    cursor: pointer;
  }

  #preview-container {
    text-align: center;
  }
  </style>
</head>
<body>
  <h1>Drag-and-Drop File Uploader</h1>
  <div id="drop-area">Drag files here to upload</div>

  <form id="upload-form" action="/" method="post" enctype="multipart/form-data">
    <input type="file" name="docfile" id="file-selector" multiple hidden>
    <div id="preview-container"></div>
  </form>

  <script type="text/javascript">

  // script.js
  const dropArea = document.getElementById('drop-area');
  const fileSelector = document.getElementById('file-selector');
  const fileInput = document.getElementById('file-selector');
  const uploadForm = document.getElementById('upload-form');

  function preventDefaults(event) {
    event.preventDefault();
    event.stopPropagation();
  }

  dropArea.addEventListener('dragover', preventDefaults);
  dropArea.addEventListener('dragenter', preventDefaults);
  dropArea.addEventListener('dragleave', preventDefaults);
  dropArea.addEventListener('drop', handleDrop);

  function handleDrop(event) {
    preventDefaults(event);
    const files = event.dataTransfer.files;
    if (files.length) {
      fileInput.files = files;
    }
  }

  </script>
</body>
</html>

How to create a drag-and-drop file uploader web page using JavaScript ?
How to create a drag-and-drop file uploader web page using JavaScript ?

Code Example 2: Enhanced with Image Previews and Highlighting

  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
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Drag-and-Drop File Uploader</title>
  <style>
  /* style.css */
  body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
  }

  h1 {
    text-align: center;
  }

  #drop-area {
    width: 400px;
    height: 200px;
    margin: 20px auto;
    border: 2px dashed #cccccc;
    text-align: center;
    line-height: 200px;
    cursor: pointer;
  }

  #preview-container {
    text-align: center;
  }

  .highlight {
    border-color: #4CAF50;
    background-color: #f0f0f0;
  }

  .preview-image {
    object-fit: cover;
    width: 100px;
    height: 100px;
    margin: 10px;
    border: 1px solid #ddd;
  }

  </style>
</head>
<body>
  <h1>Drag-and-Drop File Uploader</h1>
  <div id="drop-area">Drag file here to upload</div>

  <form id="upload-form" action="/" method="post" enctype="multipart/form-data">
    <input type="file" name="docfile" id="file-selector" multiple hidden>
    <div id="preview-container"></div>
  </form>

  <script type="text/javascript">

  // script.js
  const dropArea = document.getElementById('drop-area');
  const fileSelector = document.getElementById('file-selector');
  const fileInput = document.getElementById('file-selector');
  const uploadForm = document.getElementById('upload-form');

  function preventDefaults(event) {
    event.preventDefault();
    event.stopPropagation();
  }

  dropArea.addEventListener('dragover', preventDefaults);
  dropArea.addEventListener('dragenter', preventDefaults);
  dropArea.addEventListener('dragleave', preventDefaults);
  dropArea.addEventListener('drop', handleDrop);

  function handleDrop(event) {
    preventDefaults(event);
    const files = event.dataTransfer.files;
    if (files.length) {
      fileInput.files = files;
      previewFiles(files);
    }
  }

  dropArea.addEventListener('dragover', () => {
     dropArea.classList.add('highlight');
   });
   dropArea.addEventListener('dragleave', () => {
     dropArea.classList.remove('highlight');
   });

   function previewFiles(files) {
     const previewContainer = document.getElementById('preview-container');
     previewContainer.innerHTML = '';
     Array.from(files).forEach(file => {
       const reader = new FileReader();
       reader.readAsDataURL(file);
       reader.onloadend = function () {
         const img = document.createElement('img');
         img.src = reader.result;
         img.classList.add('preview-image');
         previewContainer.appendChild(img);
       };
     });
   }

  </script>
</body>
</html>

How to create a drag-and-drop file uploader web page using JavaScript ?
How to create a drag-and-drop file uploader web page using JavaScript ?

Code Example 3: Adding a function to ensure only allowed file types

  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
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Drag-and-Drop File Uploader</title>
    <style>
      /* style.css */
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 20px;
      }

      h1 {
        text-align: center;
      }

      #drop-area {
        width: 400px;
        height: 200px;
        margin: 20px auto;
        border: 2px dashed #cccccc;
        text-align: center;
        line-height: 200px;
        cursor: pointer;
      }

      #preview-container {
        text-align: center;
      }

      .highlight {
        border-color: #4CAF50;
        background-color: #f0f0f0;
      }

      .preview-image {
        object-fit: cover;
        width: 100px;
        height: 100px;
        margin: 10px;
        border: 1px solid #ddd;
      }
    </style>
  </head>
  <body>
    <h1>Drag-and-Drop File Uploader</h1>
    <div id="drop-area">Drag file here to upload</div>

    <form id="upload-form" action="/" method="post" enctype="multipart/form-data">
      <input type="file" name="docfile" id="file-selector" multiple hidden>
      <div id="preview-container"></div>
    </form>

    <script type="text/javascript">

      // script.js
      const dropArea = document.getElementById('drop-area');
      const fileSelector = document.getElementById('file-selector');
      const fileInput = document.getElementById('file-selector');
      const uploadForm = document.getElementById('upload-form');

      const placeholderIcon = 'document-309065_1280.png';

      function preventDefaults(event) {
        event.preventDefault();
        event.stopPropagation();
      }

      function isValidFileType(file) {
        const allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
        return allowedTypes.includes(file.type);
      }

      dropArea.addEventListener('dragover', preventDefaults);
      dropArea.addEventListener('dragenter', preventDefaults);
      dropArea.addEventListener('dragleave', preventDefaults);
      dropArea.addEventListener('drop', handleDrop);

      function handleDrop(event) {
        preventDefaults(event);
        const files = event.dataTransfer.files;
        if (files.length) {
          fileInput.files = files;
          previewFiles(files);
        }
      }

      dropArea.addEventListener('dragover', () => {
         dropArea.classList.add('highlight');
       });
       dropArea.addEventListener('dragleave', () => {
         dropArea.classList.remove('highlight');
       });

      function previewFiles(files) {
        const previewContainer = document.getElementById('preview-container');
        previewContainer.innerHTML = '';
        Array.from(files).forEach(file => {
          if (isValidFileType(file)) {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onloadend = function () {
              const img = document.createElement('img');
              img.src = reader.result;
              img.classList.add('preview-image');
              previewContainer.appendChild(img);
            };
          } else {
            alert(`File type not supported: ${file.txt}`);
          }
        });
      }

    </script>
  </body>
  </html>

References

For further reading and more advanced implementations, consider the following resources:

Links Site
how-to-make-a-drag-and-drop-file-uploader Uploadcare Blog
MDN Web Docs: Drag and Drop API Mozilla Developer Network
HTML5 Drag and Drop Tutorial Smashing Magazine

These resources offer in-depth explanations and examples to help you further enhance and customize your drag-and-drop file uploader.

Image

of