erweiterter Beitragseditor
content ist nun im json-Format Bilder können hochgeladen werden Textblöcke können im Editor angehangen werden
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Editor-Steuerung für dynamische Inhaltsblöcke
|
||||
*/
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const form = document.getElementById("editor-form");
|
||||
|
||||
// Falls das Formular auf der aktuellen Seite nicht existiert, Skript abbrechen
|
||||
if (!form) {
|
||||
return;
|
||||
}
|
||||
|
||||
const container = document.getElementById("block-container");
|
||||
const plusButton = document.getElementById("plus-button");
|
||||
const popup = document.getElementById("block-popup");
|
||||
const hiddenContentInput = document.getElementById("content");
|
||||
|
||||
// Pop-up umschalten bei Klick auf das Plus
|
||||
plusButton.addEventListener("click", () => {
|
||||
popup.classList.toggle("hidden");
|
||||
});
|
||||
|
||||
// Klick auf eine Block-Option im Pop-up
|
||||
popup.querySelectorAll("button").forEach(btn => {
|
||||
btn.addEventListener("click", function() {
|
||||
const type = this.getAttribute("data-type");
|
||||
addBlockElement(type, "");
|
||||
popup.classList.add("hidden");
|
||||
});
|
||||
});
|
||||
|
||||
// Erstellt ein visuelles HTML-Element im Editor
|
||||
function addBlockElement(type, value = "") {
|
||||
const blockDiv = document.createElement("div");
|
||||
blockDiv.classList.add("editor-block");
|
||||
blockDiv.setAttribute("data-type", type);
|
||||
|
||||
// Löschen-Button für den Block
|
||||
const deleteBtn = document.createElement("button");
|
||||
deleteBtn.type = "button";
|
||||
deleteBtn.innerHTML = "✕";
|
||||
deleteBtn.classList.add("delete-block-btn");
|
||||
deleteBtn.addEventListener("click", () => {
|
||||
blockDiv.remove();
|
||||
});
|
||||
blockDiv.appendChild(deleteBtn);
|
||||
|
||||
if (type === "text") {
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.placeholder = "Schreibe deinen Textblock...";
|
||||
textarea.value = value;
|
||||
blockDiv.appendChild(textarea);
|
||||
} else if (type === "image") {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = "image/*";
|
||||
|
||||
const imgPreview = document.createElement("img");
|
||||
imgPreview.style.maxWidth = "200px";
|
||||
imgPreview.style.display = "block";
|
||||
imgPreview.style.marginTop = "10px";
|
||||
|
||||
// Falls bereits ein Bildpfad existiert (z.B. nach einem Reload bei Validierungsfehlern)
|
||||
if (value && typeof value === 'string' && value.startsWith('uploads/')) {
|
||||
imgPreview.src = value;
|
||||
blockDiv.setAttribute("data-value", value);
|
||||
}
|
||||
|
||||
fileInput.addEventListener("change", function() {
|
||||
if (this.files && this.files[0]) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
imgPreview.src = e.target.result;
|
||||
// Temporäre Speicherung des Base64-Strings im HTML-Attribut
|
||||
blockDiv.setAttribute("data-value", e.target.result);
|
||||
}
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
}
|
||||
});
|
||||
|
||||
blockDiv.appendChild(fileInput);
|
||||
blockDiv.appendChild(imgPreview);
|
||||
}
|
||||
|
||||
container.appendChild(blockDiv);
|
||||
}
|
||||
|
||||
// Beim Abschicken: HTML-Blöcke auslesen und als JSON-String serialisieren
|
||||
form.addEventListener("submit", function(e) {
|
||||
const blocks = [];
|
||||
container.querySelectorAll(".editor-block").forEach(blockDiv => {
|
||||
const type = blockDiv.getAttribute("data-type");
|
||||
let value = "";
|
||||
|
||||
if (type === "text") {
|
||||
value = blockDiv.querySelector("textarea").value;
|
||||
} else if (type === "image") {
|
||||
value = blockDiv.getAttribute("data-value") || "";
|
||||
}
|
||||
|
||||
blocks.push({ type: type, value: value });
|
||||
});
|
||||
|
||||
// JSON-Daten in das unsichtbare Formularfeld schreiben
|
||||
hiddenContentInput.value = JSON.stringify(blocks);
|
||||
});
|
||||
|
||||
// Existierende Blöcke laden (stellt alte Daten aus der Session wieder her)
|
||||
try {
|
||||
const initialBlocks = JSON.parse(hiddenContentInput.value);
|
||||
if (Array.isArray(initialBlocks)) {
|
||||
initialBlocks.forEach(b => addBlockElement(b.type, b.value));
|
||||
}
|
||||
} catch(e) {
|
||||
// Fallback für alten Reintext aus Altbeständen
|
||||
if (hiddenContentInput.value.trim() !== "") {
|
||||
addBlockElement("text", hiddenContentInput.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user