Handling Cancel Events for Input File Upload

· 2 min read

Recently, while handling file uploads, I needed to know if the user clicked cancel. I looked into the feasibility and here’s a summary of my findings.

<input type="file"/>

JavaScript Doesn’t Support This Natively

First, there’s no official solution. If a user opens the file selection dialog and then clicks cancel, JavaScript doesn’t expose an event to tell us about the cancellation. Therefore, we need a HACK solution here. Of course, if you can accept adding another layer of dialog, that’s also possible - where users subjectively click a cancel button we provide.

HACK Solution

Here’s the HACK approach:

// fileEl is the inputFile element
const files = await new Promise((resolve) => {
      fileEl.onchange = async (_e) => {
        const { files } = fileEl;
        resolve(files);
      };
      fileEl.onclick = (_e) => {
        fileEl.value = null;
      };
      document.body.onfocus = () => {
        setTimeout(() => {
          if (fileEl.files.length === 0) {
            resolve(fileEl.files);
          }
        }, 500);
      };
    });
  1. The execution order of onchange, onclick, and onfocus is: onfocus -> onclick -> onchange
  2. When users click cancel on the dialog, onfocus will definitely trigger. Considering that onfocus also executes first when files are selected, and because there’s a delay in fileEl getting file information, we add a timeout and check file length to ensure the logic works correctly
  3. The reason for clearing the value in onclick is that if the same file is selected again, onchange won’t trigger. You can remove this if you don’t have this requirement

Official Forum

There’s discussion about this requirement in the official forum, but it’s not yet supported:

https://www.w3.org/Bugs/Public/show_bug.cgi?id=25452