mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2026-02-04 10:35:30 +00:00
+Image upload
This commit is contained in:
@@ -150,6 +150,8 @@
|
||||
autocomplete="off"
|
||||
class="w-full dbform"
|
||||
method="POST"
|
||||
enctype="multipart/form-data"
|
||||
hx-boost="false"
|
||||
action="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit">
|
||||
<input type="hidden" name="csrf_token" value="{{ $model.csrf_token }}" />
|
||||
|
||||
@@ -343,5 +345,65 @@
|
||||
deleteDialog.close();
|
||||
});
|
||||
});
|
||||
|
||||
const form = document.querySelector("form.dbform");
|
||||
const uploadInput = document.querySelector("[data-role='content-images-upload-input']");
|
||||
const userMessage = document.getElementById("user-message");
|
||||
if (form && uploadInput && userMessage) {
|
||||
form.addEventListener("submit", async (event) => {
|
||||
event.stopImmediatePropagation();
|
||||
const files = Array.from(uploadInput.files || []);
|
||||
if (files.length > 0) {
|
||||
const hasInvalid = files.some((file) => !file.type || !file.type.startsWith("image/"));
|
||||
if (hasInvalid) {
|
||||
event.preventDefault();
|
||||
userMessage.innerHTML = `
|
||||
<div class="text-red-800 text-sm mt-2 rounded-xs bg-red-200 p-2 font-bold border-red-700 shadow border mb-3">
|
||||
<i class="ri-error-warning-fill"></i> Bitte nur Bilddateien auswählen.
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
const payload = new FormData(form);
|
||||
if (payload.has("scans")) {
|
||||
payload.delete("scans");
|
||||
}
|
||||
const imagesComponent = document.querySelector("content-images");
|
||||
if (imagesComponent && typeof imagesComponent.getPendingFiles === "function") {
|
||||
imagesComponent.getPendingFiles().forEach((file) => {
|
||||
payload.append("scans", file);
|
||||
});
|
||||
if (typeof imagesComponent.getPendingDeletes === "function") {
|
||||
imagesComponent.getPendingDeletes().forEach((fileName) => {
|
||||
payload.append("scans_delete[]", fileName);
|
||||
});
|
||||
}
|
||||
}
|
||||
const response = await fetch(form.action, {
|
||||
method: form.method || "POST",
|
||||
body: payload,
|
||||
credentials: "same-origin",
|
||||
});
|
||||
if (response.redirected && response.url) {
|
||||
window.location.assign(response.url);
|
||||
return;
|
||||
}
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
const html = await response.text();
|
||||
if (!html) {
|
||||
return;
|
||||
}
|
||||
const doc = new DOMParser().parseFromString(html, "text/html");
|
||||
const nextMessage = doc.getElementById("user-message");
|
||||
if (nextMessage) {
|
||||
userMessage.innerHTML = nextMessage.innerHTML;
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -4,8 +4,11 @@
|
||||
{{- $isNew := index . "is_new" -}}
|
||||
|
||||
{{- if or $content.ImagePaths (not $isNew) -}}
|
||||
<div class="w-full" data-role="content-images-panel">
|
||||
<div class="flex flex-col items-start gap-2">
|
||||
<div class="w-full inputwrapper" data-role="content-images-panel">
|
||||
<div class="inputlabelrow">
|
||||
<label class="inputlabel">Scans</label>
|
||||
</div>
|
||||
<div class="flex flex-col items-start gap-2 p-2">
|
||||
<content-images
|
||||
class="w-full"
|
||||
data-images='[{{- range $i, $scan := $content.ImagePaths -}}{{- if $i }},{{ end -}}{{ printf "%q" $scan }}{{- end -}}]'
|
||||
@@ -15,7 +18,8 @@
|
||||
data-csrf-token="{{ $csrf }}">
|
||||
</content-images>
|
||||
{{- if not $isNew -}}
|
||||
<div class="flex" data-role="content-images-upload">
|
||||
<div class="hidden" data-role="content-images-upload">
|
||||
<input type="hidden" name="content_id" value="{{ $content.Id }}" />
|
||||
<label
|
||||
for="content-{{ $content.Id }}-scan-upload"
|
||||
class="flex h-28 w-28 items-center justify-center rounded-xs border-2 border-dashed border-slate-300 bg-stone-50 text-lg font-semibold text-slate-600 transition hover:border-slate-400 hover:text-slate-800"
|
||||
@@ -30,7 +34,6 @@
|
||||
accept="image/*"
|
||||
class="sr-only"
|
||||
data-role="content-images-upload-input"
|
||||
data-upload-endpoint="/almanach/{{ $entry.MusenalmID }}/contents/upload"
|
||||
data-content-id="{{ $content.Id }}"
|
||||
data-csrf-token="{{ $csrf }}" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user