import Dropzone from "dropzone"; import {DirectUpload} from "activestorage" import $ from 'jquery'; class ActiveStorageDropzone { constructor(dropzoneClass, uploaderClass) { this.DropzoneClass = dropzoneClass || Dropzone this.UploaderClass = uploaderClass || DirectUpload } init(element) { var acceptedFiles = $(element).data("accepted-files") || "image/*"; var dictDefaultMessage = $(element).data("placeholder") || "Drop files here"; var submitButton = $($(element).data("submit-button")); var that = this; this.myDropzone = new this.DropzoneClass(element, { url: "/", autoQueue: true, acceptedFiles: acceptedFiles, parallelUploads: 30, dictDefaultMessage: dictDefaultMessage, init: function () { this.on("sending", (file, xhr, formData) => { var createUpload = (dropzone, upload) => { upload.create((error, blob) => { if (error) { dropzone.emit("error", file, this.options.dictUploadCanceled); } else { const hiddenField = document.createElement('input'); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("value", blob.signed_id); hiddenField.name = name; document.querySelector('form').appendChild(hiddenField); dropzone.emit("success", file); dropzone.emit("complete", file); } // In either case, re-enable the provided submit button if (submitButton) { submitButton.prop("disabled", false); } }); } // Disable any provided submit button if (submitButton) { submitButton.prop("disabled", true); } // Cancel the default server request xhr.addEventListener("loadstart", () => { xhr.abort(); }); // Start the direct upload var input = document.getElementById(element.dataset.fileInputId); var name = input.name; var url = input.dataset.directUploadUrl; var delegate = { directUploadWillStoreFileWithXHR: (request) => { request.upload.addEventListener("progress", (event) => { this.emit("uploadprogress", file, 100 * (event.loaded / event.totalSize), event.loaded); }); } } var upload = new that.UploaderClass(file, url, delegate); createUpload(this, upload); }); this.on("addedfile", function(file) { // Show download link in dropzone previews let div = document.createElement("div"); let anchor = document.createElement("a"); let download_icon = " Download"; anchor.innerHTML = download_icon; anchor.href = file.dataURL; anchor.setAttribute('target', '_blank'); anchor.setAttribute('style', 'background-color: rgba(255, 255, 255, 0.4); padding: 0 0.4em; border: 1px solid transparent; text-decoration: none;'); div.append(anchor); div.setAttribute('class', 'dz-download-link') div.setAttribute('style', 'margin-top: 1em;') $(file.previewElement.childNodes[3]).append(div); }); }, }); var addExistingFiles = (dropzone, files) => { files.forEach((file, index) => { var width = dropzone.options.thumbnailWidth; var height = dropzone.options.thumbnailHeight; var method = dropzone.options.thumbnailMethod; var thumbFn = (thumbnail) => { this.myDropzone.emit('thumbnail', file, thumbnail); } dropzone.emit("addedfile", file); if (file.type.indexOf("image") >= 0) { dropzone.createThumbnailFromUrl(file, width, height, method, true, thumbFn, "Anonymous"); } dropzone.emit("complete", file); }) } // Add existing files to the dropzone const existingFiles = $(element).data("existingFiles") addExistingFiles(this.myDropzone, existingFiles); } } Dropzone.autoDiscover = false; export default ActiveStorageDropzone; document.addEventListener("turbolinks:load", function () { $("[data-behavior=dropzone]").each(function (index, element) { const dropzone = new ActiveStorageDropzone dropzone.init(element); }); });