All About Uploading

This demonstration showcases more features of the FileTransfer service:

  • It is possible to upload multiple files in a single HTTP transaction using multipart post.
  • You may specify post variables dynamically from javascript
  • The uploader should seamlessly drop in to replace existing HTML only uploading forms.
  • Full progress is accessible to JavaScript
  • The response body from the server is passed back to javascript.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
<html>
  <head><title>More Uploading...</title>
  <style type="text/css" media="screen">  
    #dropArea { width: 600px; height:100px; border: 1px solid #999; }  
    #dropTable th { background: #ccc; padding: 4px; }
  </style>    
</head>

<body>
  <p>
    <div id="dropNotes"> loading ... </div>
    <div id="dropArea"> </div>
    Progress: <span id="fileProgress">...</span>/<span id="totalProgress">...</span>
    <h2>Server Response:</h2>
    <pre id="serverResponse"></pre>
</body>  
<script src="http://bp.yahooapis.com/2.9.9/browserplus-min.js"></script>  
<script class="javascript">
// a convenience function to alter the content of the "dropNotes" div
// to give user feedback
function setDropAreaTitle(txt) {
  var div = document.getElementById("dropNotes");
  while (div.firstChild) {div.removeChild(div.firstChild);}
  div.appendChild(document.createTextNode(txt));
}

// a function that will be invoked when the user is hovering over
// the drop target.
function hovering(hoverOn) {
  if (hoverOn) {setDropAreaTitle("drop it!");}
  else {setDropAreaTitle("drag more files the box below");}
} 

function updateProgress(p) {
  var tp = document.getElementById("totalProgress");
  var fp = document.getElementById("fileProgress");
  tp.innerHTML = p.totalPercent;
  fp.innerHTML = p.filePercent;
} 

// a function invoked when the user drops content on the target
function dropped(arg) {
  var filesToUpload = {};
  var id = 0;
  for (var i = 0; i < arg.length; i++) {
    // skip folders
	if (arg[i].mimeType == "application/x-folder") continue;
	filesToUpload["file" + id++] = arg[i];
  }
  BrowserPlus.FileTransfer.upload(
	{
	  files: filesToUpload,
	  url:   "/misc/upload.php",
	  postvars: {
        foo: "bar",
		baz: "bing"
	  },
	  progressCallback: updateProgress
	}, function(r) {
	  var o = document.getElementById("serverResponse");
	  o.innerHTML = r.value.body;
	});
}

BrowserPlus.init(function(res) {
  if (res.success) {
   BrowserPlus.require({
      services: [
		{service: 'DragAndDrop', version: "1"},
		{service: 'FileTransfer', version: "1"},
		{service: 'FileChecksum', version: "1" }
	  ]},
      function(res) {
        if (res.success) {
          var dnd = BrowserPlus.DragAndDrop;
          dnd.AddDropTarget(
            {
			  id: "dropArea"
			},
            function(res) {
              dnd.AttachCallbacks({
                id: "dropArea",
                hover: hovering,
                drop: dropped
              },
              function(){});  
            setDropAreaTitle("why not drag some files to the box below?");
          });
        } else {
          alert("Error Loading DragAndDrop: " + res.error);
        }
      });
  } else {
    alert("Failed to initialize BrowserPlus: " + res.error);
  }
}); 
</script> 
</html>
Run Example

NOTE: Our servers impose upload limits of 2mb per file and 8mb per transaction.

This demonstration simply outputs the json response generated by the server php into a <pre> section. Here is the full 'upload.php' server bit:

$uploadErrors = array(
    UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
    UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
    UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
    UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
    UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
    UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
    UPLOAD_ERR_EXTENSION => 'File upload stopped by extension.'
);

header("Content-type: text/plain");

echo "{\n";
echo "  'post_variables': {\n"; 
foreach ($_POST as $k => $v) {
    echo "    " . $k . ": '" . $v . "'\n";
}
echo "  },\n"; 
echo "  files: [\n";

for ($x = 0; $x < sizeof($_FILES); $x++) {
    echo "    {\n";
    $ec = $_FILES[$x]['error'];

    if ($ec !== UPLOAD_ERR_OK)
    {
        if (isset($uploadErrors[$ec])) {
            echo "      error: '" . $uploadErrors[$ec] . "',\n";
        } else {
            echo "      error: 'unknown error',\n";
        }
    }
    echo "      size: " . $_FILES[$x]['size'] . ",\n";
    echo "      name: '" . $_FILES[$x]['name'] . "',\n";
    echo "      md5: '" . md5(file_get_contents($_FILES[$x]['tmp_name'])) . "'\n";
    echo "    },\n";
}

echo "  ]\n";
echo "}\n";