0

I use flow.js (doc here) to upload documents on my website.

2 ways to upload something:

  • Through an 'upload' button
  • By drag'n drop

I would like to ask confirmation from the user if the file is drag'n droppped.

You can take a look at the code below:

 this.flow.on('fileAdded', (file, event) => {


        if (event.type == 'drop') // File has been dropped
        {
            if (!confirm("ok?"))
                this.flow.removeFile(file);
        }

    });

It works but it is not user friendly as you can see below:

enter image description here

Is there another solution? I thought about using promises and custom boxes, but so far I was not able to use a promise system in conjunction with this event handler (this.flow.on('fileAdded'...).

I don't think the fileAdded event is waiting for a promise.

GalAbra
  • 5,048
  • 4
  • 23
  • 42
Bronzato
  • 9,438
  • 29
  • 120
  • 212

2 Answers2

0

The simplest way to generate an attractive, user friendly confirm dialog is to adopt something already written.

Here is something based on jQuery UI and a similar question answered here.

// static method of jQuery
(function($, $container) {
  $.confirm = function(question, title) {
    return $.Deferred(function(defer) {
      $container.html(question).dialog({
        'autoOpen': true,
        'modal': true,
        'title': title || 'Confirm',
        'buttons': {
          'Yes': defer.resolve,
          'No': defer.reject
        },
        'close': defer.reject
      });
    }).always(function() {
      $container.dialog('close');
    }).promise();
  }
}(jQuery, $('<div/>')));

Demo

You could write similar to mimic window.alert() and window.prompt()

Usage ...

jQuery.confirm(...) returns a promise, therefore you can write jQuery.confirm(...).then(...)

this.flow.on('fileAdded', (file, event) => {
    var that = this;
    if (event.type == 'drop') { // File has been dropped
        jQuery.confirm('Remove the file?').then(function() {
            that.flow.removeFile(file);
        }, function() {
            console.log('Removal of file not confirmed'); // or whatever you need to do when the action is not confirmed.
        });
    }
});

Don't forget, $.confirm(), as written above, is dependent on jQuery UI and its CSS file.

EDIT 1

The flow.js documentation isn't great but indicates that :

  • in a fileAdded handler, a file can be rejected by returning false.
  • a file can be added programmatically with Flow.addFile(file).

So with my jQuery.confirm(...) in place (and a bit of guesswork), here's something to try in the 'fileAdded' handler:

this.flow.on('fileAdded', (file, event) => {
    var flow = this.flow;
    if (event.type == 'drop') {
        jQuery.confirm('Remove the file?').then(function() {
            console.log('Removal of file confirmed');
            // flow.removeFile(file); // having returned false, this shouldn't be necessary.
        }, function() {
            console.log('Removal of file not confirmed');
            flow.addFile(file);
            // not sure if the queue will start/resume automatically; if not then try one of the following:
                // flow.upload(); 
                // flow.resume();
        });
        return false; // reject the file
    }
    return true;
});

Notes:

  1. I can't promise this is 100% correct. Comments indicate where the uncertainties lie. You may well need to run tests and be prepared to do some debugging.
  2. flow.addFile() will probably retrigger the 'fileAdded' event but your (event.type == 'drop') test should prevent you getting stuck in an infinite loop.
Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
  • Thanks for your code. Unfortunately I detected that we leave the click handler before displaying the dialog. TO show you, I updated your demo with alert messages. See here: http://jsfiddle.net/06gf2av2/2/ – Bronzato Jan 23 '18 at 15:42
  • You are missing the point. `$.confirm()` returns a promise. Anything you want executed after the dialog is closed MUST appear in one or other of the `.then()` callbacks. Any code that appears after `$.confirm(...)` will indeed execute immediately .... that's why you ain't going to do that! – Roamer-1888 Jan 23 '18 at 15:49
  • Yes I understand. So it is not possible to prevent the leaving on the 'fileAdded' ? I need to avoid the code to quit `fileAdded` event before a user choice is made... – Bronzato Jan 23 '18 at 15:57
  • After studying the (rather ghastly) flow.js documentation, I have added a suggestion to the answer. – Roamer-1888 Jan 24 '18 at 08:40
  • You should really delete your other question. It is sufficiently similar to this one to qualify as a double-ask. – Roamer-1888 Jan 24 '18 at 08:42
-1

If you only wanna execute this.flow.removeFile(file) if confirm dialog fails there should be no problem. Just in your case take care with "this" as the context changes inside promise handler.

   this.flow.on('fileAdded', (file, event) =>{
        if (event.type == 'drop') // File has been dropped
        { 
            var self = this;
            confirm().then(function ok() {
                // nothing to do
            },function cancel() {
                self.flow.removeFile(file);
            });
        }

    });
  • the problem with your solution is that the code is not waiting on the (dialog box) confirm to let the user choose the Yes or No response before continuing. Because there is no promise, the code simply continue and leave the `fileAdded` event before the user interact with the confirm dialog box... You see what i mean ? – Bronzato Jan 23 '18 at 12:44
  • confirm() is returning a promise object , hence the then() function used by promises so it's waiting for user to confirm. I have made plenty of promises inside events and i can't see no why it can't work. Once users cancel the confirm dialog it will execute self.flow.removeFile(file). – Krystian Fiertek Jan 23 '18 at 12:55
  • But I tested and it seems that `this.flow.on('fileAdded', (file, event ...` (from flow.js) is not waiting for a promise. So it does not work. – Bronzato Jan 23 '18 at 13:51