The ability to upload files is a key requirement for many Web and mobile applications, from uploading photos to social media to Posting resumes to job portals.

As Web developers, we must know that HTML provides support for native file uploads, with a little help from JavaScript. In HTML5, the File API is added to the DOM. With it, we can read FileList and the File object in it, which solves a variety of use cases for files, such as loading files locally or sending them over the network to a server for processing.

In this article, we’ll discuss 10 uses of HTML file upload support that we hope you found useful.

At any time, if you want to use these file upload features, they can be found here:

HTML file upload demo: EXPERIENCE with HTML software and Photoshop

The source code for the demo is in my Github repository, ✋ please feel free to follow me and keep updating the code through the examples, if you find it useful, please send a ⭐.

Source code repository: github.com/atapas/html…

1. Upload a single file

We can specify the input type as File to use the file uploader functionality in our Web application.

<input type="file" id="file-uploader">
Copy the code

Entering a file type allows the user to upload one or more files by button, which by default allows uploading a single file using the operating system’s local file browser.

After a successful upload, the File API reads the File object using simple JavaScript code. To read the File object, we need to listen for the File uploader’s change event.

First, get the file uploader instance by ID

const fileUploader = document.getElementById('file-uploader');
Copy the code

We then add a change event listener to read the file object after the upload, and we get the uploaded file information from the Event.target. files property.

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
});
Copy the code

Looking at the output in the browser console, notice that the File object in the FileList array has all the metadata information for the uploaded File.

Here is the code page for the same example for further exploration

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Uploading a single file</h1>
  <input type="file" id="file-uploader">
  <p>Upload the file and view the output in the browser console.</p>
  <p id="feedback"></p>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
  
  const feedback = document.getElementById('feedback');
  const msg = `File ${files[0].name}uploaded successfully! `;
  feedback.innerHTML = msg;
});
Copy the code

2. Upload multiple files

We can upload multiple files at once. To do this, we simply add a multiple attribute to the input file label.

<input type="file" id="file-uploader" multiple />
Copy the code

The File browser will now allow you to upload one or more files to upload. As in the previous example, you can add a change event handler to capture information about uploaded files. Did you notice that FileList is an array? Yes, for multiple file uploads, the array will have the following information:

Here is the CodePen link to explore multiple file uploads.

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Multi-file upload</h1>
  <input type="file" id="file-uploader" multiple>
  <p>Upload multiple files and view the output in the browser console</p>
  <p id="feedback"></p>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
  
  // show the upload feedback
  const feedback = document.getElementById('feedback');
  const msg = `${files.length}file(s) uploaded successfully! `;
            feedback.innerHTML = msg;
});
Copy the code

3. Understand file metadata

Whenever we upload a File, the File object has metadata information such as filename, size, last updated time, type, and so on, which is useful for further validation and decision-making.

// Get the file uploader by id
const fileUploader = document.getElementById('file-uploader');

// Listen for the change event and read the metadata
fileUploader.addEventListener('change'.(event) = > {
  // Get the FileList array
  const files = event.target.files;

  // Loop through the file and get metadata
  for (const file of files) {
    const name = file.name;
    const type = file.type ? file.type: 'NA';
    const size = file.size;
    const lastModified = file.lastModified;
    console.log({ file, name, type, size, lastModified }); }});Copy the code

Here is the output of a single file upload:

Use this CodePen to explore further

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Read File Metadata</h1>
  <input type="file" id="file-uploader">
  <p id="feedback"></p>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
  
  for (const file of files) {
    const name = file.name;
    const type = file.type ? file.type : 'NA';
    const size = file.size;
    const lastModified = file.lastModified;
    console.log({file, name, type, size, lastModified});
    
    const feedback = document.getElementById('feedback');
    const msg = ` File Name: ${name} <br/>
              File Size: ${size} <br/>
              File type: ${type} <br/>
              File Last Modified: The ${new Date(lastModified)}`; feedback.innerHTML = msg; }});Copy the code

4. Understand the accept attribute of files

We can use the Accept attribute to limit the types of files to be uploaded, and you may want to display only the types of images that are allowed to be viewed in PNG format when a user uploads a profile image.

<input type="file" id="file-uploader" accept=".jpg, .png" multiple>
Copy the code

In the code above, the file browser will only allow files with JPG and PNG extensions.

Note that in this case, the file browser automatically sets the file selection type to custom rather than all. However, you can always change it back to all files if needed.

Use this CodePen to explore the Accept attribute

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Only. PNG and. JPG files can be selected</h1>
  <input type="file" id="file-uploader" accept=".jpg, .png" multiple>
  <p>Upload files and see the output in browser console</p>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
});
Copy the code

5. Manage file contents

You can display the file contents after the file is successfully uploaded. For profile pictures, if the uploaded image is not shown to the user immediately after upload, it can cause confusion.

We can use the FileReader object to convert a file to a binary string. Then add a Load event listener to get the binary string when the file is successfully uploaded.

// Get an instance of FileReader
const reader = new FileReader();

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  const file = files[0];

  // Get the file object after upload and read it
  // Data as a URL binary string
  reader.readAsDataURL(file);

  // After loading, the string is processed
  reader.addEventListener('load'.(event) = > {
    // Here we create an image tag and add the image
    const img = document.createElement('img');
    imageGrid.appendChild(img);
    img.src = event.target.result;
    img.alt = file.name;
  });
});
Copy the code

Try selecting an image file in the CodePen below, and then view its rendering.

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Display file contents</h1>
  <input type="file" id="file-uploader" accept=".jpg, .jpeg, .png" >
  <div id="image-grid"></div>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');
const reader = new FileReader();
const imageGrid = document.getElementById('image-grid');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  const file = files[0];
  reader.readAsDataURL(file);
  
  reader.addEventListener('load'.(event) = > {
    const img = document.createElement('img');
    imageGrid.appendChild(img);
    img.src = event.target.result;
    img.alt = file.name;
  });
});
Copy the code

6. Verify the file size

As we’ve seen, we can read file size metadata and actually use it for file size validation, and you might allow users to upload image files up to 1MB. Let’s see how we can achieve this.

// File upload listener for change event
fileUploader.addEventListener('change'.(event) = > {
  // Read the file size
  const file = event.target.files[0];
  const size = file.size;

  let msg = ' ';

 // Check if the file size is greater than 1MB and prepare a message.
  if (size > 1024 * 1024) {
      msg = `<span style="color:red;" >The allowed file size is 1MB. The file you are trying to upload is of${returnFileSize(size)}</span>`;
  } else {
      msg = `<span style="color:green;" > A${returnFileSize(size)} file has been uploaded successfully. </span>`;
  }

  // Displays the message to the user
  feedback.innerHTML = msg;
});
Copy the code

Try uploading files of different sizes to see how the validation works

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Check file size</h1>
  <input type="file" id="file-uploader">
  
  <div id="feedback"></div  
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');
const feedback = document.getElementById('feedback');

fileUploader.addEventListener('change'.(event) = > {
  const file = event.target.files[0];
  console.log('file', file);
  
  const size = file.size;
  console.log('size', size);
  let msg = ' ';
  
  if (size > 1024 * 1024) {
    msg = `<span style="color:red;" >The allowed file size is 1MB. The file you are trying to upload is of${returnFileSize(size)}</span>`;
  } else {
    msg = `<span style="color:green;" > A${returnFileSize(size)} file has been uploaded successfully. </span>`;
  }
  feedback.innerHTML = msg;
});

function returnFileSize(number) {
  if(number < 1024) {
    return number + 'bytes';
  } else if(number >= 1024 && number < 1048576) {
    return (number/1024).toFixed(2) + 'KB';
  } else if(number >= 1048576) {
    return (number/1048576).toFixed(2) + 'MB'; }}Copy the code

7. The file upload progress is displayed

Better usability is to let your users know about the file upload process. Now we know about the FileReader and the events that read and load the file.

const reader = new FileReader();
Copy the code

FileReader has another event, called progress, that knows how much has been loaded. We can use HTML5’s Progress tag to create a progress bar with this information.

reader.addEventListener('progress'.(event) = > {
  if (event.loaded && event.total) {
    // Calculate the percentage of completion
    const percent = (event.loaded / event.total) * 100;
    // Set the value to the progress componentprogress.value = percent; }});Copy the code

Why don’t you try uploading a larger file and see how the progress bar in CodePen works? Try it on.

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>File upload progress</h1>
  <input type="file" id="file-uploader">
  
  <div id="feedback"></div>
  
  <label id="progress-label" for="progress"></label>
  <progress id="progress" value="0" max="100"> </progress>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');
const feedback = document.getElementById('feedback');
const progress = document.getElementById('progress');

const reader = new FileReader();

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  const file = files[0];
  reader.readAsDataURL(file);
  
  reader.addEventListener('progress'.(event) = > {
    if (event.loaded && event.total) {
      const percent = (event.loaded / event.total) * 100;
      progress.value = percent;
      document.getElementById('progress-label').innerHTML = Math.round(percent) + The '%';
      
      if (percent === 100) {
        let msg = `<span style="color:green;" >File <u><b>${file.name}</b></u> has been uploaded successfully.</span>`; feedback.innerHTML = msg; }}}); });Copy the code

8. Directory uploads?

Can we upload the whole directory? Well, it’s possible, but there are some limitations. There is a non-standard property called WebkitDirectory (at least at the time of this writing) that allows us to upload entire directories.

Although initially implemented only for WebKit-based browsers, WebKit Directory is also available on Microsoft Edge as well as Firefox 50 and later. But even though it has relatively broad support, it’s still not standard, and you shouldn’t use it unless you have no choice.

You can specify this property as

<input type="file" id="file-uploader" webkitdirectory />
Copy the code

This will allow you to select a folder (aka directory)

Users must provide confirmation information to upload directories,

When the user clicks the ‘Upload’ button, the Upload will take place. An important point to note here is that the FileList array will contain information about all the files in the upload directory as a flat structure. But the point is that for each File object, the webkitRelativePath property has a directory path.

For example, let’s consider a main directory with other folders and files under it,

The File object will now populate webkitRelativePath with

You can use it to render folders and files in any UI structure you choose. Use this CodePen to explore further.

CodePen: CodePen. IO/atapas/pen /…

<div>
  <h1>Upload directories</h1>
  <input type="file" id="file-uploader" webkitdirectory />
  
  <ul id="pathList"></ul>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');
const pathList = document.getElementById('pathList');

function removeAllChildNodes(parent) {
    while (parent.firstChild) {
        parent.removeChild(parent.firstChild);
    }
}

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  console.log('files', files);
  
  removeAllChildNodes(pathList);
  
  [...files].forEach((file, index) = > {
    let path = document.createElement('li');
    path.innerHTML = file.webkitRelativePath;
    pathList.appendChild(path);
  });
});
Copy the code

9. Let’s drag and drop and upload

Uploading files without drag and drop is an old way to do it, isn’t it? Let’s look at how to achieve this in a few simple steps.

First, create a drop area and an optional area to display the contents of the uploaded file. We will use the image as a file to drag and drop here.

<div id="container">
  <h1>Drag & Drop an Image</h1>
  <div id="drop-zone">
    DROP HERE
  </div>

  <div id="content">
    Your image to appear here..
  </div>
</div>
Copy the code

Get drag and content areas by their respective ids.

const dropZone = document.getElementById('drop-zone');
const content = document.getElementById('content');
Copy the code

Add a dragover event handler to show the effect of the content to be copied,

dropZone.addEventListener('dragover'.event= > {
  event.stopPropagation();
  event.preventDefault();
  event.dataTransfer.dropEffect = 'copy';
});
Copy the code

Next, to define what to do when we place the image, we’ll need a drop event listener to handle it.

dropZone.addEventListener('drop'.event= > {
  // Get the file
  const files = event.dataTransfer.files;

	// Now, we can do everything possible to display the contents of the file in an HTML element, such as DIV.
});
Copy the code

Try dragging and dropping the image file in the CodePen example below and see how it works, and don’t forget to look at the code to render the dragged image.

CodePen: CodePen. IO/atapas/pen /…

<div id="container">
  <h1>Drag & Drop an Image</h1>
  <div id="drop-zone"> DROP HERE </div>
  <div id="content">Your image to appear here.. </div>
</div>
Copy the code
const dropZone = document.getElementById('drop-zone');
const content = document.getElementById('content');

const reader = new FileReader();

if (window.FileList && window.File) {
  dropZone.addEventListener('dragover'.event= > {
    event.stopPropagation();
    event.preventDefault();
    event.dataTransfer.dropEffect = 'copy';
  });
  
  dropZone.addEventListener('drop'.event= > {
    content.innerHTML = ' ';
    event.stopPropagation();
    event.preventDefault();
    const files = event.dataTransfer.files;
    console.log(files);
    
    reader.readAsDataURL(files[0]);
  
    reader.addEventListener('load'.(event) = > {
      content.innerHTML = ' ';
      const img = document.createElement('img');
      img.style.height = '400px';
      img.style.width = '400px';
      content.appendChild(img);
      img.src = event.target.result;
      img.alt = file.name;
      
    });
  }); 
}
Copy the code

10. Use objectURLs to process files

There is a special method called url.createObjecturl () that creates a unique URL from a file, or you can release it using the url.revokeobjecturl () method.

The DOM url.createObjecturl () and url.revokeobjecturl () methods let you create simple URL strings that can be used to reference any data that can be referenced using DOM file objects, including local files on the user’s computer.

A simple use of the object URL is:

img.src = URL.createObjectURL(file);
Copy the code

Use this CodePen to further browse the object URL. Tip: Compare this approach to the one mentioned earlier in #5.

<div>
  <h1>Use Object URL</h1>
  <input type="file" id="file-uploader" accept=".jpg, .jpeg, .png" >
  
  <div id="image-grid"></div>
</div>
Copy the code
const fileUploader = document.getElementById('file-uploader');
const reader = new FileReader();
const imageGrid = document.getElementById('image-grid');

fileUploader.addEventListener('change'.(event) = > {
  const files = event.target.files;
  const file = files[0];
  
  const img = document.createElement('img');
  imageGrid.appendChild(img);
  img.src = URL.createObjectURL(file);
  img.alt = file.name;
});
Copy the code

The end of the

Most of the time, native HTML functionality is sufficient to handle the use case at hand. I’ve found that file uploads offer a lot of good options by default.


Wechat search [front-end full stack developer] pay attention to this hair loss, stall,Selling goodsContinuous learning programmers, the first time to read the latest articles, will be two days before the publication of new articles. Attention can be a gift package, you can save a lot of money!

Original text: dev. To/atapas