Skip to content

terwanerik/uppie

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

uppie

Cross-browser file and directory and upload library

uppie is a tiny library (903 bytes gzipped) which helps you with file and directory uploads in browsers. It supports all current and past implementations of multi-file and directory uploads and provides you with a FormData object you can submit directly to a server through either XMLHttpRequest or fetch. Both the <input type="file"> element and drag-and-drop are supported.

Example (also see this demo)

<input type="file" id="file-input" multiple directory webkitdirectory allowdirs/>
<script src="uppie.js"></script>
var uppie = new Uppie();

uppie(document.querySelector('#file-input'), function (event, formData, files) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/upload');
  xhr.send(formData);
});

Browser support

| | files in | files via | directories in | directories via |

input[file] drag and drop input[file] drag and drop
Firefox yes yes yes (50+) yes (50+)
Chrome yes yes yes (29+) yes (29+)
Edge yes yes yes (13+) yes (14+)
Safari yes yes no no

Notes

  • Empty directories are excluded from the results by all browsers as dictated by the spec.
  • Some browsers may excludes files and directories starting with a ..

API

uppie(node, callback)

  • node Node or NodeList: One or more DOM nodes. If a <input type="file"> is given, uppie will monitor it for change events. Any other element type will be enabled as a dropzone and watched for drop events. If you want to use both on the same element, use a hidden <input> and forward the click event.
  • callback Function: callback which is called every time the selected files change or when files are dropped in the dropzone.

The callback receives

  • event Event: the original event. Useful for calling event.stopPropagation().
  • formData FormData: FormData object to be used for XHR2 uploading.
  • files Array: Array of paths for preview purposes.

FormData format

name will always be "files[]", filename will be the full path to the file, with / used as path separator. Does not include a leading slash. Here's an example:

------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/1.txt"
Content-Type: text/plain

[DATA]
------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/path/2.txt"
Content-Type: text/plain

[DATA]
------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/path/to/3.txt"
Content-Type: text/plain

Recommended input element attributes

  • multiple: allow multiple files to be selected.
  • webkitdirectory: enable directory uploads in Chrome and Firefox.
  • allowdirs: enable experimental directory upload API in Firefox and Edge.

PHP example

Below is example for PHP 7.0 and possibly earlier versions. PHP does not parse the path from the filename field, so it is necessary to submit the path through other means, like as separate FormData fields as done in the example.

var uppie = new Uppie();
uppie(document.documentElement, function(event, formData, files) {
  Array.prototype.forEach.call(files, function(f) {
    formData.append("paths[]", f);
  });

  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'upload.php');
  xhr.send(formData);
});

And in upload.php:

foreach ($_FILES['files']['name'] as $i => $name) {
  if (strlen($_FILES['files']['name'][$i]) > 1) {
    $fullpath = strip_tags($_POST['paths'][$i]);
    $path = dirname($fullpath);

    if (!is_dir('uploads/'.$path)){
      mkdir('uploads/'.$path);
    }
    if (move_uploaded_file($_FILES['files']['tmp_name'][$i], 'uploads/'.$fullpath)) {
        echo '<li>'.$name.'</li>';
    }
  }
}

Note that PHP's upload limits might need to be raised depending on use case.

© silverwind, distributed under BSD licence

About

Cross-browser directory and multi-file upload library

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 65.1%
  • Makefile 20.1%
  • HTML 14.8%