Try it
Drop, review, submit
Drop files, a folder, or click browse. Each file cascades into the staging list with its size and type. Hover a row to rename, click × to remove, drop more onto the list to keep adding. Hit Submit to see exactly what would be posted.
Form payload
Install & usage
Drop it in
One stylesheet, one script, one attribute. No build step. Plugin auto-mounts on DOMContentLoaded.
<link rel="stylesheet" href="path/to/uploady.css">
<script src="path/to/uploady.js"></script>
<form action="/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="docs" multiple
accept="image/*,.pdf"
data-uploady
data-max-files="20"
data-max-size="10485760">
<button>Submit</button>
</form>
The plugin keeps the original <input> in the DOM and syncs its files list to whatever the user has staged. A normal form post sends every staged file under the input's name — your backend reads it like any other multi-file upload.
Drop a folder and uploady recursively flattens it: every file inside becomes one entry, folder structure discarded. Set data-retain-folders="true" to show the relative path next to each file (the file itself is still posted by its leaf name — browsers don't allow the original webkit-relative path to round-trip through input.files).
Options
Tune it with data attributes
All options are data-* attributes on the file input. Standard HTML attributes — multiple, accept — are honored.
| Attribute | Default | What it does |
|---|---|---|
data-retain-folders |
false |
If true, shows the relative path of each file in a dropped folder. If false (default), folders are silently flattened and only files are kept. |
data-animate |
true |
Cascade each new file into the list with a progress-bar staging animation. Set false to drop files in instantly. |
data-allow-rename |
true |
Show a pencil icon on hover; click (or double-click the name) to rename inline. Enter commits, Escape cancels. Extension is preserved. |
data-allow-remove |
true |
Show a × on each file. Click to remove it from the staged set before submit. |
data-max-files |
— | Cap the number of files. Extras are silently skipped and a notice appears. |
data-max-size |
— | Per-file byte limit. Oversized files appear in an error state and are excluded from the form post. |
accept |
— | Standard HTML attribute — comma-separated MIME types and/or extensions. Files that don't match show an error and are excluded from the form post. |
multiple |
— | Standard HTML attribute. Without it, uploady runs in single-file mode: each new pick replaces the prior file. |
JavaScript API
For when auto-init isn't enough
// Manual init (after injecting new file inputs)
Uploady.initAll(scope); // scan a subtree for [data-uploady]
Uploady.init(inputElement); // mount one input
// Live instance
const inst = Uploady.instances.get(inputElement);
inst.getFiles(); // -> File[] (excludes errored)
inst.getEntries(); // -> [{ id, file, status, error, relPath }]
inst.removeFile(id); // drop a file from the staged set
inst.renameFile(id, "new.pdf"); // rebuild the File with a new name
inst.reset(); // back to the empty dropzone
// Events bubble from the original input
input.addEventListener('uploady:files-added', (e) => {
console.log(e.detail.added, e.detail.all);
});
input.addEventListener('uploady:file-removed', (e) => {
console.log(e.detail.id, e.detail.file);
});
input.addEventListener('uploady:file-renamed', (e) => {
console.log(e.detail.oldName, '→', e.detail.newName);
});
input.addEventListener('uploady:reset', () => { ... });