Drag-n-Drop from Desktop jQuery Plugin
I created a jQuery plugin for uploading files using the Drag-n-drop from the desktop feature of the File API of HTML5. I’ve only used this with Firefox 3.6, which is one of the very few browsers that currently supports this feature. The plugin posts the file data the same way that a file picker input field would.
When you run the example page below, you should see the drop target div appear as a red box 100 by 100, and then when you drag a file from the desktop over the drop target it should turn green. Then you let go of the file and the page will post it to upload.xqy, just like the previous post where we used a file picker to upload.
The plugin takes three parameters:
1. The url to post the file to
2. The name of the field in the POST data that will contain the file data
3. Options for changing the class of the drop target element during drag events
Note: The code below is from an XQuery page which is why there are double braces (“{{” and “}}”) to escape the braces. Also you probably will want to serve the HTML page from a server, not the filesystem, because the browser doesn’t seem to actually post the data unless this is the case.
example HTML page
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#dragtarget {{ width: 100; height: 100 }}
.dragleave {{ background: red }}
.dragenter {{ background: green }}
</style>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="jquery.dragUploadable.js"></script>
<script type="text/javascript">
$(function()
{{
$('#dragtarget').dragUploadable("upload.xqy", "upload", {{
dragleaveClass: "dragleave",
dragenterClass: "dragenter"
}});
}});
</script>
</head>
<body>
<div id="dragtarget" class="dragleave">Drop Zone</div>
</body>
</html>
upload.xqy (same as in previous post)
let $upload-fieldname := "upload"
let $image := xdmp:get-request-field( $upload-fieldname )
let $filename := xdmp:get-request-field-filename($upload-fieldname)
let $path := fn:concat("/somewhere/", $filename)
let $doc-saved := xdmp:save($path, $image)
return $image
Save the following as “jquery.dragUploadable.js”
(function($){
$.fn.dragUploadable = function(postURL, fieldName, options) {
var defaults = {
dragenterClass: "",
dragleaveClass: ""
};
var options = $.extend(defaults, options);
return this.each(function() {
obj = $(this);
obj.bind("dragenter", function(event){
obj.removeClass(options.dragleaveClass);
obj.addClass(options.dragenterClass);
event.stopPropagation();
event.preventDefault();
}, false);
obj.bind("dragover", function(event){
event.stopPropagation();
event.preventDefault();
}, false);
obj.bind("dragleave", function(event){
obj.removeClass(options.dragenterClass);
obj.addClass(options.dragleaveClass);
event.stopPropagation();
event.preventDefault();
}, false);
obj.bind("drop", function(event){
var data = event.originalEvent.dataTransfer;
upload(postURL, fieldName, data);
event.stopPropagation();
event.preventDefault();
}, false);
});
};
})(jQuery);
function dropSetup() {
var dropContainer = document.getElementById("output");
dropContainer.addEventListener("dragenter", function(event){dropContainer.innerHTML = 'DROP';event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("drop", upload, false);
};
function upload(postURL, fieldName, data) {
var boundary = '------multipartformboundary' + (new Date).getTime();
var dashdash = '--';
var crlf = '\r\n';
/* Build RFC2388 string. */
var builder = '';
builder += dashdash;
builder += boundary;
builder += crlf;
var xhr = new XMLHttpRequest();
/* For each dropped file. */
for (var i = 0; i < data.files.length; i++) {
var file = data.files[i];
/* Generate headers. */
builder += 'Content-Disposition: form-data; name="' + fieldName + '"';
if (file.fileName) {
builder += '; filename="' + file.fileName + '"';
}
builder += crlf;
builder += 'Content-Type: application/octet-stream';
builder += crlf;
builder += crlf;
/* Append binary data. */
builder += file.getAsBinary();
builder += crlf;
/* Write boundary. */
builder += dashdash;
builder += boundary;
builder += crlf;
}
/* Mark end of the request. */
builder += dashdash;
builder += boundary;
builder += dashdash;
builder += crlf;
xhr.open("POST", postURL, true);
xhr.setRequestHeader('content-type', 'multipart/form-data; boundary='
+ boundary);
xhr.sendAsBinary(builder);
xhr.onload = function(event) {
/* Response from server */
if (xhr.responseText) {
alert(xhr.responseText);
}
};
}