import { Controller } from "@hotwired/stimulus" import { DirectUpload } from "@rails/activestorage" // Connects to data-controller="upload" export default class extends Controller { static values = { url: String, createUrl: String, parentId: Number, target: String } connect() { // console.info(this.urlValue) // console.info('URL', this.createUrlValue) } // This will be triggered when a file is selected or dropped upload(event) { event.preventDefault() const container = document.getElementById(this.targetValue) const files = event.target.files || event.dataTransfer.files; Array.from(files).forEach((file, index) => { const uid = 'new_' + Date.now() + '_' + index const target_div = document.createElement('div') target_div.setAttribute('id', uid) if (this.targetValue == 'attachments') { target_div.classList.add('attachment', 'loading') target_div.innerHTML = '0' } else if (this.targetValue == 'tree-nodes') { target_div.classList.add('row') target_div.innerHTML = '
0
' } container.append(target_div) new Uploader(this, file, uid).start() }); } // Drag over event handler dragover(event) { event.preventDefault(); this.element.classList.add('drag-over'); } // Drag leave event handler dragleave(event) { event.preventDefault(); this.element.classList.remove('drag-over'); } // Drop event handler drop(event) { event.preventDefault(); this.element.classList.remove('drag-over'); // Call the upload method and pass in the drop event this.upload(event); } } class Uploader { constructor(source, file, uid) { this.source = source this.uid = uid this.upload = new DirectUpload(file, source.urlValue, this) } start() { this.upload.create((error, blob) => { if (error) { // Handle the error } else { const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content') const formData = new FormData() if (this.source.parentIdValue > 0) { formData.append('id', this.source.parentIdValue) } formData.append('signed_id', blob.signed_id) formData.append('uid', this.uid) fetch(this.source.createUrlValue, { method: 'POST', headers: { 'Accept': "text/vnd.turbo-stream.html", 'X-CSRF-Token': token }, body: formData }) .then (response => response.text()) .then(html => Turbo.renderStreamMessage(html)) .catch((err) => { console.info('rejected', err) }) } }) } directUploadWillStoreFileWithXHR(request) { request.upload.addEventListener("progress", event => this.directUploadDidProgress(event)) } directUploadDidProgress(event) { const target = document.getElementById(this.uid).querySelector('.progress') const loaded = Math.round((event.loaded / event.total) * 100) target.innerHTML = loaded } }