Works with any backend npm install Zero dependencies

Async Validation (Promise)

Return a Promise from customValidation for server-side or async checks.

(function() {
 var logEl = document.getElementById('log');
 function log(m) { var d = document.createElement('div'); d.className='pkg-log-entry'; d.textContent=m; logEl.appendChild(d); logEl.scrollTop=logEl.scrollHeight; }
 new MultipleUpload('#demo', {
 uploadUrl: '/api/upload',
 multiple: true,
 customValidation: function(file) {
 log('Checking ' + file.name + '...');
 return new Promise(function(resolve) {
 setTimeout(function() {
 if (file.size > 10 * 1024 * 1024) {
 resolve('File exceeds 10 MB policy limit.');
 } else {
 log(file.name + ' passed async check');
 resolve(null);
 }
 }, 500);
 });
 },
 onValidationError: function(msg, name) { log((name||'file') + ': ' + msg); }
 });
})();

Checks that need the server

Some rules cannot be decided in the browser: whether a filename is already taken, whether the user has quota left, whether a document number exists. onBeforeUpload can return a promise, so the transfer waits for your answer and returning false rejects the file.

Keep it fast and fail open carefully

The user is waiting on this check with no visible upload happening, so it needs a timeout and something on screen while it runs. Decide deliberately what happens when the check itself fails: blocking the upload because a quota service was briefly down is usually worse than allowing it and re-checking on the server, which has to happen anyway.