javascriptdrag-and-drophtml5-filesystemnative-file-system-api-js

How to use html5 drag-drop functionality with FileSystemAPI?


I am using the FileSystemAPI window.showDirectoryPicker() to open a directory which is returning a handle to that directory & by using that I can traverse all the files present in that directory.

const dropArea = document.getElementById("drop_zone");
dropArea.onclick = async (evt) => {
  const dirHandle = await window.showDirectoryPicker();
  // Next lines of code using dirHandle 
};

Above piece of code working fine when use clicking on the button which is prompting the user to chose a directory. I want to achieve the same functionality with the drag & drop as well, means instead of clicking & choosing a directory user can drop a directory.

Followed below link but it didn't work for me.

https://developers.google.com/web/updates/2012/07/Drag-and-drop-a-folder-onto-Chrome-now-available#how_to_handle_dropped_folders

I will appreciate for any help or input on this. Thank you!


Solution

  • The HTML Drag and Drop interfaces enable web applications to accept dragged and dropped files on a web page. During a drag and drop operation, dragged file and directory items are associated with file entries and directory entries respectively. The DataTransferItem.getAsFileSystemHandle() method returns a promise with a FileSystemFileHandle object if the dragged item is a file, and a promise with a FileSystemDirectoryHandle object if the dragged item is a directory. The listing below shows this in action. Note that the Drag and Drop interface's DataTransferItem.kind will be "file" for both files and directories, whereas the File System Access API's FileSystemHandle.kind will be "file" for files and "directory" for directories.

    elem.addEventListener('dragover', (e) => {
      // Prevent navigation.
      e.preventDefault();
    });
    
    elem.addEventListener('drop', async (e) => {
      // Prevent navigation.
      e.preventDefault();
      // Process all of the items.
      for (const item of e.dataTransfer.items) {
        // Careful: `kind` will be 'file' for both file
        // _and_ directory entries.
        if (item.kind === 'file') {
          const entry = await item.getAsFileSystemHandle();
          if (entry.kind === 'directory') {
            handleDirectoryEntry(entry);
          } else {
            handleFileEntry(entry);
          }
        }
      }
    });