Skip to content

Instantly share code, notes, and snippets.

@ravid7000
Last active November 10, 2020 18:49
Show Gist options
  • Save ravid7000/965a32da9dae062121c39065ba5332b5 to your computer and use it in GitHub Desktop.
Save ravid7000/965a32da9dae062121c39065ba5332b5 to your computer and use it in GitHub Desktop.
<script>
s3UploadUtility({
fileInputElement: '#fileinputfield',
onFinished: function(paths) {
console.log(paths)
}
})
</script>
'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