Skip to content

Instantly share code, notes, and snippets.

@rcravens
Created March 1, 2013 20:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rcravens/5067694 to your computer and use it in GitHub Desktop.
Save rcravens/5067694 to your computer and use it in GitHub Desktop.
HTML5 Drag & Drop File Upload A demonstration of some features.
<?php
/*
HTML5 Drag & Drop File Upload with Progress
Borrowed from these original sources:
http://webstandardssherpa.com/reviews/dissecting-gmails-email-attachments/
http://www.script-tutorials.com/html5-drag-and-drop-multiple-file-uploader/
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Something is being posted:
echo "<br />_FILES<br />";
var_dump($_FILES);
exit;
}
?>
<html>
<head>
<title>Upload Test</title>
<style type="text/css">
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* SPECIFIC STYLES */
body{
margin: 10px;
background-color: #f2f2f2;
}
#wrap{
margin: 0 auto;
padding: 20px;
width: 800px;
min-height: 400px;
text-align: center;
}
#target {
background-color: #ffffff;
border: 2px solid #e2e2e2;
width: 400px;
margin: 20px auto;
color: #888;
padding: 40px 0;
font-size: 24px;
}
#info {
width: 400px;
margin: 20px auto;
padding: 40px 0;
display: none;
text-align: left;
}
#info ul {
list-style: none;
margin: 20px 0;
padding: 20px 10px;
border: 1px solid #e2e2e2;
}
#info ul li {
padding-bottom: 8px;
}
#info ul li span.name {
padding: 0 5px;
}
canvas {
background-color: #fff;
}
</style>
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div id="wrap">
<h3>Upload via HTML5 Drag-n-Drop</h3>
<div id="target">
Drop Files Here
</div>
<div id="info">
<ul id="files"></ul>
<button id="clear">clear</button>
</div>
</div>
<script type="text/javascript">
(function(){
var list = [];
var bytes_uploaded = [];
var index = 0;
function processFiles(files) {
if(!files || !files.length || list.length) {
return;
}
console.log(files);
index = -1;
list = [];
bytes_uploaded = [];
var ul = $('#files');
ul.html();
var len=files.length;
for(var i=0; i<len; i++) {
list.push(files[i]);
bytes_uploaded.push(10);
var li = $('<li id="file' + i + '">');
li.append('<span class="progress"><canvas width="200" height="20"></canvas></span>');
li.append('<span class="name">' + files[i].name + '</span>');
ul.append(li);
}
$('#info').slideToggle('fast');
for(var i=0; i<len; i++){
drawProgress(i);
}
uploadNext();
}
function uploadNext() {
if(list.length){
index++;
if(index<list.length){
var nextFile = list[index];
uploadFile(nextFile);
}
}
}
function uploadFile(file) {
var xhr = new XMLHttpRequest();
xhr.open("post", "/upload/", true);
xhr.onload = function() {
console.log('onload');
switch(this.status) {
case 200: //request complete and successful
handleComplete(file.size);
console.log("Files uploaded");
break;
default: // request complete but with unexpected response
console.log("Files not uploaded.");
}
};
xhr.onerror = function() {
console.log('onerror');
handleComplete(file.size);
}
xhr.upload.onprogress = function(event) {
console.log('onprogress');
handleProgress(event);
}
xhr.upload.onloadstart = function(event) {
console.log('onloadstart');
}
var formData = new FormData();
formData.append('myfile', file);
xhr.send(formData);
}
function drawProgress(i) {
if(i==undefined){
i = index;
}
console.log(i);
var progress = bytes_uploaded[i]/list[i].size;
var canvas = $('#file' + i + ' canvas');
var width = canvas.width();
var height = canvas.height();
var context = canvas[0].getContext('2d');
context.clearRect(0, 0, width, height);
context.beginPath();
context.strokeStyle = '#4b9500';
context.fillStyle = '#4b9500';
context.fillRect(0, 0, progress * width, height);
context.closePath();
context.font = '12px Verdana';
context.fillStyle = '#000';
context.fillText(Math.floor(progress*100) + '%', 50, 15);
}
function handleComplete(size) {
bytes_uploaded[index] = size;
drawProgress();
uploadNext();
}
function handleProgress(event) {
console.log(event);
bytes_uploaded[index] = event.loaded;
drawProgress();
}
function handleDrag(event) {
event.preventDefault();
event.stopPropagation();
switch(event.type) {
case "dragenter":
document.body.className = "dragging";
break;
case "dragover":
break;
case "dragleave":
document.body.className = "";
break;
case "drop":
console.log('drop');
if(event.target.id == "target") {
console.log("Dropped %d files.", event.dataTransfer.files.length);
processFiles(event.dataTransfer.files);
}
break;
}
}
document.addEventListener("dragenter", handleDrag, false);
document.addEventListener("dragover", handleDrag, false);
document.addEventListener("dragleave", handleDrag, false);
document.addEventListener("drop", handleDrag, false);
console.log('listening. . . . ');
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment