Thursday, April 15th, 2010
Drag and drop file uploads in Gmail using just the specs
<p>Gmail started off with the awfulinput type="file" "add more" typical solution that we all know and love. Then they added the ability to select multiple files via Flash.... and now they allow the ability to drag and drop files right onto the message compose using HTML5 standards.

Want to do it too? Check out the APIs and how you can do it all, including showing the thumbnails:
-
-
function handleFiles(files) {
-
for (var i = 0; i <files.length; i++) {
-
var file = files[i];
-
var imageType = /image.*/;
-
-
if (!file.type.match(imageType)) {
-
continue;
-
}
-
-
var img = document.createElement("img");
-
img.classList.add("obj");
-
img.file = file;
-
preview.appendChild(img);
-
-
var reader = new FileReader();
-
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
-
reader.readAsDataURL(file);
-
}
-
}
-








Cool stuff – unfortunately it only works in Firefox 3.6 until WebKit gets their File API story together (hopefully soon!)
Hm, Google blog post says Chrome too – done via Gears or something?
@codedread – Safari/Chrome allow you to drag and drop files into file inputs which can than trigger a change event on the input which will upload them.
Awesome :)
It does indeed work in Chrome, allthough there is no
FileReaderglobal object to be found. So the snippet above will only work in Firefox 3.6.I have tried to figure out how this is implemented in chrome, but haven’t found out anything.
Oh wait, the article updated since I read it on my phone, and no longer use the
FileReader. Never mind!Meh, you do use
FileReader. (Sidenote: I’m too used to having edit/delete buttons)I’m still awaiting for more browser support for the FileAPI spec – it’s going to be soooooo nice once in place!
How is Chrome doing this given that it doesn’t yet support getAsBinary or FileReader?
This is EXTREMELY bad code. I’m really disappointed of the writer, no matter if it’s someone from Google or from Ajaxian. NEVER INITALIZE VARIABLES IN A LOOP is something every experienced Javascript developer should know. I optimized it here: http://vincentrolfs-59vls.posterous.com/better-code
It seems like Chrome can send the file object entirely like this:
var file = data.files[i];
…. create XMLHttpRequest etc…
xhr.setRequestHeader(‘Content-Type’, ‘multipart/form-data’);
xhr.setRequestHeader(‘X-File-Name’, file.fileName);
xhr.setRequestHeader(‘X-File-Size’, file.fileSize);
xhr.send(file);
Then all you have to do is read the inputstream and headers on the server and save the file :-)
@hakonvik – Where did you find that information? I have had trouble finding any information about how chrome / safari upload files using File objects
@silentchris – Safari/Chrome/Firefox all support the XHR2 upload method which allows you to upload files asyncronously
saw it here: http://stackoverflow.com/questions/2657653/drag-and-drop-file-upload-in-chromium
Tried to find documentation for hours with no luck, seems like google is holding back how they do it for now…
@JSkid – “EXTREMELY bad code”? Bit of a code smell, but far from bad. Initializing most of the variables will add almost nothing to the code; pretending it’s life or death is silly. I’d say extremely bad code is code that is prematurely optimized, especially when it detracts from readability…
Do you seriously think a couple of variable initializations is the bottle neck in a loop that creates an HTML image element and appends it to the DOM in each iteration? The initializations will be, literally, negligible in the running time of this algorithm.