Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find if 'cancel' was clicked on file input

I tried using a hack described in various locations which uses:

document.body.onfocus = checkOnCancel();

An example:

var fileSelectEle = document.getElementById('fileinput');

fileSelectEle.onclick = charge;

function charge()
{
    document.body.onfocus = checkOnCancel;
}

function checkOnCancel()
{
    alert("FileName:" + fileSelectEle.value + "; Length: " + fileSelectEle.value.length);
    if(fileSelectEle.value.length == 0) alert('You clicked cancel!')
    else alert('You selected a file!');
    document.body.onfocus = null;
}

Is there something wrong here? Because fileSelectedEle.value always returns the previous execution value and NOT the one selected by the user. Is this the expected behavior of input file? How to resolve this to read the actual file selected?

http://jsfiddle.net/smV9c/2/

You can reproduce the error by:

Step 1: SelectFile - some select some file (and notice the output)

Step 2: SelectFile - press cancel (and notice the output)

like image 352
SamSharma Avatar asked Apr 06 '14 19:04

SamSharma


1 Answers

One solution is to use the onchange event of the input.

var fileSelectEle = document.getElementById('fileinput');

fileSelectEle.onchange = function ()
{
  if(fileSelectEle.value.length == 0) {
    alert('You clicked cancel - ' + "FileName:" + fileSelectEle.value + "; Length: " + fileSelectEle.value.length);
  } else {
    alert('You selected a file - ' + "FileName:" + fileSelectEle.value + "; Length: " + fileSelectEle.value.length);
  }
}

This responds correctly to changes in the selected filename, as you can test here: http://jsfiddle.net/munderwood/6h2r7/1/

The only potential difference in behaviour from the way you were trying to do it, is that if you cancel right away, or twice in a row, or select the same file twice in a row, then the event won't fire. However, every time the filename actually changes, you'll detect it correctly.

I don't know for sure why your original attempt didn't work, although my best guess is that it's a timing issue with the onfocus event firing asynchronously, and before the input control's properties have finished updating.

UPDATE: To determine what the user has selected every time they close the file dialog, even if nothing has changed, the timing issue can be skirted by adding a brief delay between receiving focus again, and checking the value of the file input. Instead of calling checkOnCancel immediately upon receiving focus, the following version of charge causes it to be called a tenth of a second later.

function charge() {
  document.body.onfocus = function () { setTimeout(checkOnCancel, 100); };
}

Here's a working version: http://jsfiddle.net/munderwood/6h2r7/2/.

like image 161
Michael Avatar answered Sep 17 '22 08:09

Michael