app/javascript/satis/controllers/attachment_upload_controller.js in satis-2.1.49 vs app/javascript/satis/controllers/attachment_upload_controller.js in satis-2.1.50
- old
+ new
@@ -1,45 +1,67 @@
import { Controller } from "@hotwired/stimulus"
+import { post } from "@rails/request.js"
export default class AttachmentUploadController extends Controller {
- static targets = ["input"]
+ static targets = ["button"]
+ static values = {
+ url: String,
+ parameterName: String
+ }
+
connect() {
this.createFileInput()
this.addEventListeners()
}
+ disconnect() {
+ this.fileInput.removeEventListener("change", this.handleChange.bind(this))
+ this.element.removeEventListener("dragover", this.handleDragOver.bind(this))
+ this.element.removeEventListener("dragleave", this.handleDragLeave.bind(this))
+ this.element.removeEventListener("dragenter", this.handleDragEnter.bind(this))
+ this.element.removeEventListener("drop", this.handleDrop.bind(this))
+ }
+
createFileInput() {
+ // Mimic rails - this hiddenInput should prevent "old" files from being deleted
+ const hiddenInput = document.createElement("input")
+ hiddenInput.setAttribute("name", `${this.parameterNameValue}[]`)
+ hiddenInput.setAttribute("type", "hidden")
+ hiddenInput.setAttribute("autocomplete", "off")
+
+ this.element.closest('form').appendChild(hiddenInput)
+
const input = document.createElement("input")
- input.setAttribute("name", this.data.get("param-name") || "file")
+
+ input.setAttribute("name", `${this.parameterNameValue}[]`)
input.setAttribute("type", "file")
input.setAttribute("multiple", "multiple")
input.style.display = "none"
- this.element.appendChild(input)
- this.fileInput = input
- if (!this.data.has("param-name")) {
- console.warn(this.element, "has no data-upload-param attribute, uploads may not work")
- }
+ this.element.closest('form').appendChild(input)
+ this.fileInput = input
}
addEventListeners() {
- this.element.addEventListener("click", this.handleClick.bind(this))
this.fileInput.addEventListener("change", this.handleChange.bind(this))
this.element.addEventListener("dragover", this.handleDragOver.bind(this))
this.element.addEventListener("dragleave", this.handleDragLeave.bind(this))
this.element.addEventListener("dragenter", this.handleDragEnter.bind(this))
this.element.addEventListener("drop", this.handleDrop.bind(this))
}
handleClick(event) {
- event.preventDefault()
this.fileInput.click()
}
handleChange(event) {
- this.upload(event.target.files)
+ if (this.hasUrlValue) {
+ this.upload(event.target.files)
+ } else {
+ this.buttonTarget.innerHTML = `${event.target.files.length} files selected`
+ }
}
handleDragOver(event) {
event.preventDefault()
this.element.classList.add("dragging")
@@ -57,53 +79,33 @@
handleDrop(event) {
event.preventDefault()
this.element.classList.remove("dragging")
if (event.dataTransfer.files.length > 0) {
- this.upload(event.dataTransfer.files)
+ if (this.hasUrlValue) {
+ this.upload(event.dataTransfer.files)
+ } else {
+ this.buttonTarget.innerHTML = `${event.dataTransfer.files.length} files selected`
+ }
}
}
upload(files) {
// Only proceed if files are selected
if (files.length === 0) return
let formData = new FormData()
- if (this.data.has("extra-data")) {
- for (let [key, value] of Object.entries(JSON.parse(this.data.get("extra-data")))) {
- formData.append(key, value)
- }
- }
for (let i = 0; i < files.length; i++) {
- formData.append(this.data.get("param-name"), files[i])
+ formData.append("attachments", files[i])
}
this.element.classList.add("uploading")
- fetch(this.data.get("url"), {
- method: 'POST',
+ post(this.urlValue, {
body: formData,
- headers: {
- 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
- 'Accept': 'text/html, application/json'
- },
- redirect: 'follow' // Important: follow redirects
- }).then((response) => {
- // Check if the response is a redirect
- if (response.type === 'opaqueredirect' || response.redirected) {
- window.location.href = response.url
- return
- }
-
- if (response.ok) {
- this.element.classList.remove("uploading")
- window.location.reload(true)
- } else {
- throw new Error(response.statusText)
- }
- }).catch((error) => {
- console.log(error)
+ responseKind: 'turbo-stream'
+ }).then(html => {
this.element.classList.remove("uploading")
})
}
}