123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /*
- Resources:
- - https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications
- - https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/
- - https://eloquentjavascript.net/18_http.html
- */
-
- application.register(
- 'upload-images',
- class extends Stimulus.Controller {
- static get targets() {
- return ['input', 'output', 'dropzone']
- }
-
- openFileSelector() {
- this.inputTarget.click()
- }
- addActiveClass(event) {
- event.preventDefault()
- this.dropzoneTarget.classList.add('active')
- }
- removeActiveClass() {
- this.dropzoneTarget.classList.remove('active')
- }
-
- handleImages(event) {
- event.preventDefault()
- let images = []
- if (event.type == 'change') {
- images = event.target.files
- } else if (event.type == 'drop') {
- images = event.dataTransfer.files
- }
- Array.from(images).forEach(image => {
- const imageName = image.name
- const imageSize = image.size
- const isOversized =
- Math.round(imageSize / 1024) >
- Number(this.data.get('maxSizeKb'))
-
- if (isOversized) {
- this.outputTarget.classList.add('oversized')
- this.outputTarget.innerText = 'Oversized!'
- this.inputTarget.value = ''
- return
- } else {
- this.outputTarget.classList.remove('oversized')
- this.outputTarget.innerText = ''
- this.dropzoneTarget.classList.add('hidden')
- }
-
- const figure = document.createElement('figure')
-
- const img = document.createElement('img')
- img.file = image // Required for future upload, fragile?
- img.src = window.URL.createObjectURL(image)
- img.onload = event =>
- window.URL.revokeObjectURL(event.target.src)
- img.alt = 'Picture preview'
- figure.appendChild(img)
-
- const figcaption = document.createElement('figcaption')
- figcaption.innerText = imageName
- figure.appendChild(figcaption)
-
- this.outputTarget.appendChild(figure)
- })
- }
-
- submit(event) {
- event.preventDefault()
- const images = this.outputTarget.querySelectorAll('img')
- Array.from(images).forEach(image => {
- const formdata = new FormData()
- formdata.append('images', image.file)
- const options = {
- method: this.element.method,
- body: formdata
- }
- console.log(`Uploading "${image.file.name}"`)
- this._request(
- this.element.action,
- options,
- this._displayPercentage
- )
- .then(response => console.log('Uploaded!'))
- .catch(console.log.bind(console))
- })
- }
-
- _request(url, options = {}, onProgress) {
- // See https://github.com/github/fetch/issues/89#issuecomment-256610849
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest()
- xhr.open(options.method || 'get', url)
- for (let header in options.headers || {})
- xhr.setRequestHeader(header, options.headers[header])
- xhr.onload = event => resolve(event.target.responseText)
- xhr.onerror = reject
- if (xhr.upload && onProgress) xhr.upload.onprogress = onProgress
- xhr.send(options.body)
- })
- }
-
- _displayPercentage(event) {
- if (event.lengthComputable) {
- const percentage = Math.round(
- (event.loaded * 100) / event.total
- )
- console.log(percentage)
- }
- }
- }
- )
|