Dragging and dropping files from your desktop to a browser is one of
the ultimate goals for web application integration. This is the first in
a four-part series of posts from SitePoint which describes how to:
- Enable file dragging and dropping onto a web page element
- Analyze dropped files in JavaScript
- Load and parse files on the client
- Asynchronously upload files to the server using XMLHttpRequest2
- Show a graphical progress bar while the upload occurs
- Use progressive enhancement to ensure your file upload form works in any browser
- Code it in plain ol’ JavaScript without a library.
Step:1 Copy and Paste
File Name: filedrag.js (you must use this filename exactly)
(function() {
// getElementById
function $id(id) {
return document.getElementById(id);
}
// output information
function Output(msg) {
var m = $id("messages");
m.innerHTML = msg + m.innerHTML;
}
// file drag hover
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
}
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f);
}
}
// output file information
function ParseFile(file) {
Output(
"<p>File information: <strong>" + file.name +
"</strong> type: <strong>" + file.type +
"</strong> size: <strong>" + file.size +
"</strong> bytes</p>"
);
}
// initialize
function Init() {
var fileselect = $id("fileselect"),
filedrag = $id("filedrag"),
submitbutton = $id("submitbutton");
// file select
fileselect.addEventListener("change", FileSelectHandler, false);
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// file drop
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
filedrag.style.display = "block";
// remove submit button
submitbutton.style.display = "none";
}
}
// call initialization file
if (window.File && window.FileList && window.FileReader) {
Init(); }
})();
// getElementById
function $id(id) {
return document.getElementById(id);
}
// output information
function Output(msg) {
var m = $id("messages");
m.innerHTML = msg + m.innerHTML;
}
// file drag hover
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
}
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f);
}
}
// output file information
function ParseFile(file) {
Output(
"<p>File information: <strong>" + file.name +
"</strong> type: <strong>" + file.type +
"</strong> size: <strong>" + file.size +
"</strong> bytes</p>"
);
}
// initialize
function Init() {
var fileselect = $id("fileselect"),
filedrag = $id("filedrag"),
submitbutton = $id("submitbutton");
// file select
fileselect.addEventListener("change", FileSelectHandler, false);
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// file drop
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
filedrag.style.display = "block";
// remove submit button
submitbutton.style.display = "none";
}
}
// call initialization file
if (window.File && window.FileList && window.FileReader) {
Init(); }
})();
Step:2 Copy and Paste
File Name: styles.css (you must use this filename exactly)
body
{
font-family: "Segoe UI", Tahoma, Helvetica, freesans, sans-serif;
font-size: 90%;
margin: 10px;
color: #333;
background-color: #fff;
}
h1, h2
{
font-size: 1.5em;
font-weight: normal;
}
h2
{
font-size: 1.3em;
}
legend
{
font-weight: bold;
color: #333;
}
#filedrag
{
display: none;
font-weight: bold;
text-align: center;
padding: 1em 0;
margin: 1em 0;
color: #555;
border: 2px dashed #555;
border-radius: 7px;
cursor: default;
}
#filedrag.hover
{
color: #f00;
border-color: #f00;
border-style: solid;
box-shadow: inset 0 3px 4px #888;
}
img
{
max-width: 100%;
}
pre
{
width: 95%;
height: 8em;
font-family: monospace;
font-size: 0.9em;
padding: 1px 2px;
margin: 0 0 1em auto;
border: 1px inset #666;
background-color: #eee;
overflow: auto;
}
#messages
{
padding: 0 10px;
margin: 1em 0;
border: 1px solid #999;
}
#progress p
{
display: block;
width: 240px;
padding: 2px 5px;
margin: 2px 0;
border: 1px inset #446;
border-radius: 5px;
background: #eee url("progress.png") 100% 0 repeat-y;
}
#progress p.success
{
background: #0c0 none 0 0 no-repeat;
}
#progress p.failed
{
background: #c00 none 0 0 no-repeat;
}
{
font-family: "Segoe UI", Tahoma, Helvetica, freesans, sans-serif;
font-size: 90%;
margin: 10px;
color: #333;
background-color: #fff;
}
h1, h2
{
font-size: 1.5em;
font-weight: normal;
}
h2
{
font-size: 1.3em;
}
legend
{
font-weight: bold;
color: #333;
}
#filedrag
{
display: none;
font-weight: bold;
text-align: center;
padding: 1em 0;
margin: 1em 0;
color: #555;
border: 2px dashed #555;
border-radius: 7px;
cursor: default;
}
#filedrag.hover
{
color: #f00;
border-color: #f00;
border-style: solid;
box-shadow: inset 0 3px 4px #888;
}
img
{
max-width: 100%;
}
pre
{
width: 95%;
height: 8em;
font-family: monospace;
font-size: 0.9em;
padding: 1px 2px;
margin: 0 0 1em auto;
border: 1px inset #666;
background-color: #eee;
overflow: auto;
}
#messages
{
padding: 0 10px;
margin: 1em 0;
border: 1px solid #999;
}
#progress p
{
display: block;
width: 240px;
padding: 2px 5px;
margin: 2px 0;
border: 1px inset #446;
border-radius: 5px;
background: #eee url("progress.png") 100% 0 repeat-y;
}
#progress p.success
{
background: #0c0 none 0 0 no-repeat;
}
#progress p.failed
{
background: #c00 none 0 0 no-repeat;
}
Step:3 Copy and Paste
File Name: drag.htm (you can change the filename to anything you like)
<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<title>HTML5 File Drag & Drop API</title>
<link rel="stylesheet" type="text/css" media="all" href="index_files/styles.css">
<style type="text/css" charset="utf-8">/* See license.txt for terms of usage */
/** reset styling **/
.firebugResetStyles {
z-index: 2147483646 !important;
top: 0 !important;
left: 0 !important;
display: block !important;
border: 0 none !important;
margin: 0 !important;
padding: 0 !important;
outline: 0 !important;
min-width: 0 !important;
max-width: none !important;
min-height: 0 !important;
max-height: none !important;
position: fixed !important;
-moz-transform: rotate(0deg) !important;
-moz-transform-origin: 50% 50% !important;
-moz-border-radius: 0 !important;
-moz-box-shadow: none !important;
background: transparent none !important;
pointer-events: none !important;
}
.firebugBlockBackgroundColor {
background-color: transparent !important;
}
.firebugResetStyles:before, .firebugResetStyles:after {
content: "" !important;
}
/**actual styling to be modified by firebug theme**/
.firebugCanvas {
display: none !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.firebugLayoutBox {
width: auto !important;
position: static !important;
}
.firebugLayoutBoxOffset {
opacity: 0.8 !important;
position: fixed !important;
}
.firebugLayoutLine {
opacity: 0.4 !important;
background-color: #000000 !important;
}
.firebugLayoutLineLeft, .firebugLayoutLineRight {
width: 1px !important;
height: 100% !important;
}
.firebugLayoutLineTop, .firebugLayoutLineBottom {
width: 100% !important;
height: 1px !important;
}
.firebugLayoutLineTop {
margin-top: -1px !important;
border-top: 1px solid #999999 !important;
}
.firebugLayoutLineRight {
border-right: 1px solid #999999 !important;
}
.firebugLayoutLineBottom {
border-bottom: 1px solid #999999 !important;
}
.firebugLayoutLineLeft {
margin-left: -1px !important;
border-left: 1px solid #999999 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.firebugLayoutBoxParent {
border-top: 0 none !important;
border-right: 1px dashed #E00 !important;
border-bottom: 1px dashed #E00 !important;
border-left: 0 none !important;
position: fixed !important;
width: auto !important;
}
.firebugRuler{
position: absolute !important;
}
.firebugRulerH {
top: -15px !important;
left: 0 !important;
width: 100% !important;
height: 14px !important;
border-top: 1px solid #BBBBBB !important;
border-right: 1px dashed #BBBBBB !important;
border-bottom: 1px solid #000000 !important;
}
.firebugRulerV {
top: 0 !important;
left: -15px !important;
width: 14px !important;
height: 100% !important;
border-left: 1px solid #BBBBBB !important;
border-right: 1px solid #000000 !important;
border-bottom: 1px dashed #BBBBBB !important;
}
.overflowRulerX > .firebugRulerV {
left: 0 !important;
}
.overflowRulerY > .firebugRulerH {
top: 0 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.fbProxyElement {
position: fixed !important;
pointer-events: auto !important;
}</style></head>
<body>
<h1>HTML5 File Drag & Drop API</h1>
<p>This is a demonstration of the HTML5 drag & drop API which retrieves file information.</p>
<p><a href="http://www.webihawk.com">Web i HawK</a></p>
<form id="upload" action="index.html" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>HTML File Upload</legend>
<input id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" type="hidden">
<div>
<label for="fileselect">Files to upload:</label>
<input id="fileselect" name="fileselect[]" multiple="multiple" type="file">
<div style="display: block;" id="filedrag">or drop files here</div>
</div>
<div style="display: none;" id="submitbutton">
<button type="submit">Upload Files</button>
</div>
</fieldset>
</form>
<div id="messages">
<p>Status Messages</p>
</div>
<h2><script src="index_files/filedrag.js"></script>
</h2>
</body></html>
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<title>HTML5 File Drag & Drop API</title>
<link rel="stylesheet" type="text/css" media="all" href="index_files/styles.css">
<style type="text/css" charset="utf-8">/* See license.txt for terms of usage */
/** reset styling **/
.firebugResetStyles {
z-index: 2147483646 !important;
top: 0 !important;
left: 0 !important;
display: block !important;
border: 0 none !important;
margin: 0 !important;
padding: 0 !important;
outline: 0 !important;
min-width: 0 !important;
max-width: none !important;
min-height: 0 !important;
max-height: none !important;
position: fixed !important;
-moz-transform: rotate(0deg) !important;
-moz-transform-origin: 50% 50% !important;
-moz-border-radius: 0 !important;
-moz-box-shadow: none !important;
background: transparent none !important;
pointer-events: none !important;
}
.firebugBlockBackgroundColor {
background-color: transparent !important;
}
.firebugResetStyles:before, .firebugResetStyles:after {
content: "" !important;
}
/**actual styling to be modified by firebug theme**/
.firebugCanvas {
display: none !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.firebugLayoutBox {
width: auto !important;
position: static !important;
}
.firebugLayoutBoxOffset {
opacity: 0.8 !important;
position: fixed !important;
}
.firebugLayoutLine {
opacity: 0.4 !important;
background-color: #000000 !important;
}
.firebugLayoutLineLeft, .firebugLayoutLineRight {
width: 1px !important;
height: 100% !important;
}
.firebugLayoutLineTop, .firebugLayoutLineBottom {
width: 100% !important;
height: 1px !important;
}
.firebugLayoutLineTop {
margin-top: -1px !important;
border-top: 1px solid #999999 !important;
}
.firebugLayoutLineRight {
border-right: 1px solid #999999 !important;
}
.firebugLayoutLineBottom {
border-bottom: 1px solid #999999 !important;
}
.firebugLayoutLineLeft {
margin-left: -1px !important;
border-left: 1px solid #999999 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.firebugLayoutBoxParent {
border-top: 0 none !important;
border-right: 1px dashed #E00 !important;
border-bottom: 1px dashed #E00 !important;
border-left: 0 none !important;
position: fixed !important;
width: auto !important;
}
.firebugRuler{
position: absolute !important;
}
.firebugRulerH {
top: -15px !important;
left: 0 !important;
width: 100% !important;
height: 14px !important;
border-top: 1px solid #BBBBBB !important;
border-right: 1px dashed #BBBBBB !important;
border-bottom: 1px solid #000000 !important;
}
.firebugRulerV {
top: 0 !important;
left: -15px !important;
width: 14px !important;
height: 100% !important;
border-left: 1px solid #BBBBBB !important;
border-right: 1px solid #000000 !important;
border-bottom: 1px dashed #BBBBBB !important;
}
.overflowRulerX > .firebugRulerV {
left: 0 !important;
}
.overflowRulerY > .firebugRulerH {
top: 0 !important;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.fbProxyElement {
position: fixed !important;
pointer-events: auto !important;
}</style></head>
<body>
<h1>HTML5 File Drag & Drop API</h1>
<p>This is a demonstration of the HTML5 drag & drop API which retrieves file information.</p>
<p><a href="http://www.webihawk.com">Web i HawK</a></p>
<form id="upload" action="index.html" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>HTML File Upload</legend>
<input id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" type="hidden">
<div>
<label for="fileselect">Files to upload:</label>
<input id="fileselect" name="fileselect[]" multiple="multiple" type="file">
<div style="display: block;" id="filedrag">or drop files here</div>
</div>
<div style="display: none;" id="submitbutton">
<button type="submit">Upload Files</button>
</div>
</fieldset>
</form>
<div id="messages">
<p>Status Messages</p>
</div>
<h2><script src="index_files/filedrag.js"></script>
</h2>
</body></html>