marinosoftware / active_storage_drag_and_drop

Provides a form helper to make it easy to make drag-and-drop file upload fields that work with Rails' Active Storage.
MIT License
92 stars 14 forks source link

Upload without form submit #4

Closed StefanRitchie closed 5 years ago

StefanRitchie commented 5 years ago

Hi,

I'm trying to trigger file uploads as soon as they're dropped into the dndzone, and I'm just not succeeding. I'm hoping you can help. I'm sure I'm just misunderstanding something. Here's my code:


const form = document.getElementsByClassName('form-with-dnd');

function TriggerProcessUploadQueue(form, event) {
    console.log(event.detail);

    //Start the upload

    let callback = function(error) {
        if (error) {
            console.log('An error was found:');
            console.log(error);
            console.log('This upload will be aborted');
        } else {
            console.log("No errors were detected with this item");
            console.log("Let's upload it now...");
        }
    };

    const uploadEvent = document.createEvent('Event');
    uploadEvent.initEvent('dnd-uploads:process-upload-queue', true, true);
    uploadEvent.detail = { callback };
    form.dispatchEvent(uploadEvent);
}

document.addEventListener('dnd-upload:initialize', function (event) {
    console.log('This item was dropped on the box, or selected from dialog:');
    TriggerProcessUploadQueue(form[0], event);
});

When I step through the code in Chrome Dev Tools I find that the file is present in the detail attribute of event (demonstrated by console.log(event.detail)) but at the below block of code in ujs.js, the nextUpload.current_uploaders.length is equal to 0:

function processUploadQueue (event) {
  const form = event.target
  const { callback } = event.detail
  const nextUpload = new UploadQueueProcessor(form)
  if (nextUpload.current_uploaders.length > 0) {
    nextUpload.start(error => {
      if (error) {
        callback(error)
      } else {
        callback()
      }
    })
  } else {
    callback()
  }
}

I can confirm the form being passed to UploadQueueProcessor is the correct form DOM element.

I'm certain I must be overlooking something obvious, as it all seems to tie together nicely!

IanGrantMarino commented 5 years ago

Hi Stefan,

Apologies, the events aren't as clear as they should be and may see some refactoring/better documentation soon. At the time that the 'dnd-upload:initialize' event is triggered the uploads are not yet in the queue. It is more for overriding the default UI when an file is added.

We might add some more callbacks in the future to make this clearer but for now you should be able to get the functionality you're looking for by listening for the 'drop' event instead.

document.addEventListener('drop', function (event) {
    if(!event.target.closest('.asdndzone')) { return; }

    console.log('This item was dropped on the box, or selected from dialog:');
    TriggerProcessUploadQueue(form[0]);
});
StefanRitchie commented 5 years ago

Thank you very much for your help! I'll close this issue as my needs have been satisfied 👍

iraszl commented 5 years ago

@MatrixStefan Did you get it working? Is every file uploading separately upon dropping it into the dropzone? Could you kindly provide the code and a short explanation of what needs to be done? It would be much appreciated!