4

In a web browser, when a user clicks on a file field to upload a file the browser displays a file upload dialogue (at least in Windows and OSX).

Let's assume the user changes his mind and cancels the file upload. Can we find out?

We can find out if the user hits the escape key (that usually closes the file dialogue). But what if the user clicks on "Cancel" or tabs over to "Cancel" and hits enter?

Jumbalaya Wanton
  • 1,601
  • 1
  • 25
  • 47
  • It depends on the method being used to upload the file. iFrame, Ajax, etc. You could definitely catch those events and handle them, but again, depends on what you utilize to upload. – Jose Jan 08 '14 at 17:39
  • What stops you from checking the value-attribute of said file input field? – Sumurai8 Jan 08 '14 at 17:40
  • @Jose I don't think so. It's pretty simple. If the user clicks cancel on the Native OS file selection dialog, we either can tell, or we can't. I am not concerned with what happens after the dialogue is closed. – Jumbalaya Wanton Jan 08 '14 at 17:47
  • @Sumurai8 I have an event on `blur()` attached to the file field. I want it to run all the time, unless the bluring happened because the file selection box was opened. I don't think that's possible, so the next best thing is to detect if it were canceled and handle the event appropriately. – Jumbalaya Wanton Jan 08 '14 at 17:50

3 Answers3

1

First of all, I want to stress that <input type="file" /> will not upload the file automatically, unless you do something with ajax or the user submits the form. The user just tells the browser where it can find the file in case the user wants to submit the form at some point.

To find out what happened I made this script. The tab doesn't register if I put it on the input-field, so I put it on the parent of the input field instead. The rest works based on that it executes handlers in the order they were attached.

If the user takes more than 1/10th of a second to choose a file (or cancel the upload), which is almost always the case. I set data with the timestamp when a certain action happens that would gain the input field focus, that isn't by closing the upload dialog (e.g. by choosing a file or by hitting escape/clicking cancel). If the input field gets focus within 1/10th of a second when that happens, I know it isn't the event we are looking for. The second thing we check, is if the value changes. If the user cancels the dialog, the value doesn't change. That is when the user has canceled the dialog... somehow... and still want to upload the same file. If the value does change, the user changed their mind about what file to upload. The file doesn't update until the user submits the forum though.


HTML:

<input type="file" id="example" />

Javascript (with jquery):

$(document).ready( function() {
    $('#example').parent().on( 'keydown', function(e) {
        var key = e.key || e.keyCode || e.which;
        if( key == "Tab" || key == 9) {
            $('#example').data( 'actiontime', +new Date() );
        }
    } );

    $('#example').on( 'blur', function() {
        $(this).data( 'lastval', $(this).val() );
    } ).on('mousedown', function() {
        $(this).data( 'actiontime', +new Date() );
    } ).on('focus', function() {
        var fastevents = new Date() - $(this).data( 'actiontime' ) < 100;
        if( $(this).data( 'lastval' ) == undefined ) {
            console.log( 'First run' );
        } else if( $(this).data( 'lastval' ) != $(this).val() && !fastevents ) {
            console.log( 'Input changed' );
        } else if( !fastevents ) {
            console.log( 'User canceled dialog somehow' );
        } else {
            console.log( 'Other event' );
        }
    });
});
Sumurai8
  • 20,333
  • 11
  • 66
  • 100
0

Yes, have the upload button trigger a function in the first place.

Then send a server Ajax request about it.

Log this server side.

Then if no file is uploaded before you get another request or time out > The user cancelled the upload.

The D Merged
  • 680
  • 9
  • 17
0
  1. When the user clicks on the Select File button, use JavaScript event handler to run a function.
  2. Run a loop continuously until the user clicks somewhere on body.

  3. Inside the loop, check if input file is changed.

or you can try how-to-detect-when-cancel-is-clicked-on-file-input

RupamDotInfo
  • 57
  • 12
  • Does this actually work? I mean, I would have thought an onclick handler on the body would not work if you're synchronously blocking the thread. Either way, synchronous blocking is generally seen as bad practice. – Aidy J Feb 21 '19 at 16:38