Last active
November 10, 2020 18:49
-
-
Save ravid7000/965a32da9dae062121c39065ba5332b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
s3UploadUtility({ | |
fileInputElement: '#fileinputfield', | |
onFinished: function(paths) { | |
console.log(paths) | |
} | |
}) | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
function parseURL (text) { | |
var xml = new window.DOMParser().parseFromString(text, 'text/xml') | |
var tag = xml.getElementsByTagName('Key')[0] | |
return decodeURI(tag.childNodes[0].nodeValue) | |
} | |
function waitForAllFiles (form) { | |
if (window.uploading !== 0) { | |
setTimeout(function () { | |
waitForAllFiles(form) | |
}, 100) | |
} else { | |
window.HTMLFormElement.prototype.submit.call(form) | |
} | |
} | |
function request (method, url, data, fileInput, file, form) { | |
file.loaded = 0 | |
return new Promise(function (resolve, reject) { | |
var xhr = new window.XMLHttpRequest() | |
xhr.open(method, url) | |
xhr.onload = function () { | |
if (xhr.status === 201) { | |
resolve(xhr.responseText) | |
} else { | |
reject(xhr.statusText) | |
} | |
} | |
xhr.upload.onprogress = function (e) { | |
var diff = e.loaded - file.loaded | |
form.loaded += diff | |
fileInput.loaded += diff | |
file.loaded = e.loaded | |
var defaultEventData = { | |
currentFile: file, | |
currentFileName: file.name, | |
currentFileProgress: Math.min(e.loaded / e.total, 1), | |
originalEvent: e | |
} | |
form.dispatchEvent(new window.CustomEvent('progress', { | |
detail: Object.assign({ | |
progress: Math.min(form.loaded / form.total, 1), | |
loaded: form.loaded, | |
total: form.total | |
}, defaultEventData) | |
})) | |
fileInput.dispatchEvent(new window.CustomEvent('progress', { | |
detail: Object.assign({ | |
progress: Math.min(fileInput.loaded / fileInput.total, 1), | |
loaded: fileInput.loaded, | |
total: fileInput.total | |
}, defaultEventData) | |
})) | |
} | |
xhr.onerror = function () { | |
reject(xhr.statusText) | |
} | |
xhr.send(data) | |
}) | |
} | |
function uploadFiles (form, fileInput) { | |
var url = fileInput.getAttribute('data-url') | |
fileInput.loaded = 0 | |
fileInput.total = 0 | |
var promises = Array.from(fileInput.files).map(function (file) { | |
form.total += file.size | |
fileInput.total += file.size | |
var s3Form = new window.FormData() | |
Array.from(fileInput.attributes).forEach(function (attr) { | |
var name = attr.name | |
if (name.startsWith('data-fields')) { | |
name = name.replace('data-fields-', '') | |
s3Form.append(name, attr.value) | |
} | |
}) | |
s3Form.append('success_action_status', '201') | |
s3Form.append('Content-Type', file.type) | |
s3Form.append('file', file) | |
return request('POST', url, s3Form, fileInput, file, form) | |
}) | |
return new Promise((resolve, reject) => { | |
Promise.all(promises).then(function (results) { | |
var keys = results.map(function (result) { | |
return parseURL(result) | |
}) | |
window.uploading -= 1 | |
resolve(keys) | |
}, function (err) { | |
console.log(err) | |
fileInput.setCustomValidity(err) | |
fileInput.reportValidity() | |
reject(err) | |
}) | |
}) | |
} | |
function s3UploadUtility(options) { | |
var defaultOptions = Object.assign({ | |
fileInputElement: '', | |
onFinished: function() {} | |
}, options) | |
if (defaultOptions.fileInputElement) { | |
var input = document.querySelector(defaultOptions.fileInputElement); | |
var form = input.closest('form') | |
window.uploading = 0 | |
form.loaded = 0 | |
form.total = 0 | |
form.addEventListener('submit', function (e) { | |
e.preventDefault() | |
window.uploading += 1 | |
uploadFiles(e.target, input, input.name).then(defaultOptions.onFinished) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment