ProgerXP / FileDrop

Self-contained cross-browser pure JavaScript class for Drag & Drop and AJAX (multi) file upload.
filedropjs.org
The Unlicense
264 stars 61 forks source link

Adjacent zones intermingle .fd-file css #24

Open DevlshOne opened 10 years ago

DevlshOne commented 10 years ago

I'm setting up a file repository type module in one of my apps and am using a combination of jQuery FileTree and FileDrop to allow the end user to upload files to multiple folders by displaying multiple drop zones. However, The CSS that is recommended for use with .fd-file seems to overlap zones and destroy the functionality of the click / browse. Has anyone tweaked this CSS to allow zone overlaps?

ProgerXP commented 10 years ago

The point about overlapping CSS zones is that it provides legacy (and by now I would say very legacy) support for no-D&D upload (not FF/Chrome/Safari/Opera). It works by creating an element that's relatively positioned and with hidden overflow, putting an <input type=file> inside and giving that input maximum possible transparency and font size so it will likely fill the entire parent element. That parent element, in turn, clips the input. This way when you drop a file onto the element you are actually dropping it onto the input.

In your case I see two approaches:

edit: I should probably mention that IE10 still doesn't support D&D but it's fairly rare so it might be worth having two versions of your page since nobody can deny the beauty of proper CSS/HTML.

DevlshOne commented 10 years ago

Removing the iframe option worked wonderfully, thanks! I am in a PURE Chrome environment, so 95% of the time, my clients should be using DnD. However, for that other 5%, take a look at the image attached. How can I allow them to click the folder icon to restore click/browse functionality? It looks as if the FIleDrop handle may be what I want but haven't I ruled that out by shutting down iframe? Your help is greatly appreciated, as is this awesome jQ extension! dropzone

ProgerXP commented 10 years ago

Hardly any problem there - simply create new FileDrop zone for every folder icon you have. A zone isn't necessary that standard <fieldset><legend>... markup - it can be bound to really any kind of element with any children. Therefore nobody prevents you from having something like this:

<span id="drawings_legacy"><img></span>

$('#drawings_legacy').filedrop()

The only downside is that you will have to handle both D&D and this legacy drop zones but if you reuse your code properly this won't be a problem.

It looks as if the FIleDrop handle may be what I want but haven't I ruled that out by shutting down iframe?

You can't toggle legacy/HTML5 upload on the fly (not a good idea, it will need to add/remove event listeners, somehow prevent DOM structure, etc.) but it's not user-friendly either so I think the above approach will work better for you.

DevlshOne commented 10 years ago

So far, all of your suggestions have been GREAT! I've actually solved the whole thing by tweaking the .fd-file CSS to include the area around the folder icon. Now I have a new problem... my $_FILES global in PHP is always empty. The console reports that each file is being processed correctly, being POST'd to my AJAX call and my progress events are working.

Here's my file processing function in JavaScript:

var processUploads = function(f,subdir) {
        $.each(f, function (i, file) {
            console.log('Processing ' + file.name);
            file.event('sendXHR', function() {
                $('#fileprog').progressbar({value:0,max:file.size});
            });
            file.event('progress', function(curr) {
                $('#fileprog').progressbar({value:curr});
            });
            file.sendTo('ajax/ajax.receiveFile.php?subdir=' + subdir + '&job_id=' + job_id);
        });
    };

And here's my PHP:

require_once ( 'init.php' );
var_dump($_FILES);
ob_start();
$callback = &$_REQUEST['fd-callback'];
$job_id = &$_REQUEST['job_id'];
$subdir = &$_REQUEST['subdir'];
$j = loadJob($job_id);
$save_path = "D:\\JobFiles\\" . $j->gOrderNumber() . "\\" . $subdir . "\\";
if ( ($_FILES['fd-file']['size'] > 0) && is_uploaded_file($_FILES['fd-file']['tmp_name']) ) {
  $name = $_FILES['fd-file']['name'];
  if (move_uploaded_file($_FILES['fd-file']['tmp_name'], $save_path.$name)) {
    $j->addAttachment($subdir,$name);
    echo 'true';
  } else {
    echo 'false';
  }
}
ob_end_flush();
ProgerXP commented 10 years ago

First off, sendXHR is now xhrSend (since FileDrop v2), by analogy with added xhrSetup. The former still works but is deprecated.

Second, you're not using FileDrop right - check included upload.php, you will see that $_FILES is used for legacy iframe uploads while php://input (RAW_POST_DATA) is used fpr modern AJAX uploads. This means that if you upload via iframe it's exactly like normal <form enctype="multipart/form-data" method="post"> but with AJAX you upload raw data, you get no file name, nothing, so $_FILES is not populated - this kind of metadata (info about, er, data) you can get from $_SERVER['HTTP_X_FILE_NAME'] and other X- headers. Once again, check the included upload.php.

DevlshOne commented 10 years ago

Got it! Thanks for all of your help!