//console.log("editor.js wurde erfolgreich geladen!"); function initEditor() { const form = document.getElementById("editor-form"); if (!form) { console.error("editor.js abgebrochen: Formular nicht gefunden!"); return; } else { console.log("Formular gefunden und editor.js initialisiert:", form); } const container = document.getElementById("block-container"); const plusButton = document.getElementById("plus-button"); const popup = document.getElementById("block-popup"); // Fortlaufender Zähler für eindeutige Block-Indizes. Wird nie wiederverwendet // (auch nicht nach dem Löschen eines Blocks), damit sich neue und übrig // gebliebene Blöcke beim finalen Submit nie einen Namen teilen. let blockIndex = container.querySelectorAll(".editor-block").length; // Ohne JS sind Textblock-/Bild-Button im Pop-up immer sichtbar und ganz normale // Submit-Buttons. Erst mit JS blenden wir das Pop-up standardmäßig aus und // steuern die Sichtbarkeit über den Plus-Button. popup.classList.add("hidden"); plusButton.addEventListener("click", () => { popup.classList.toggle("hidden"); }); // Klick auf "Textblock" / "Bild einfügen": lokal im DOM anlegen statt zum // Server zu submitten (entlastet den Server, kein Page-Reload nötig). popup.querySelectorAll('[name="editor_action"]').forEach(btn => { btn.addEventListener("click", function (e) { e.preventDefault(); const type = this.getAttribute("data-type"); addBlockElement(type, ""); popup.classList.add("hidden"); }); }); // Bereits vom Server gerenderte Blöcke (z.B. beim Bearbeiten eines bestehenden // Artikels oder nach einem Validierungsfehler) ebenfalls mit JS-Verhalten ausstatten. container.querySelectorAll(".editor-block").forEach(blockDiv => { bindDeleteButton(blockDiv); bindImageInput(blockDiv); }); // Erstellt einen neuen Block inkl. echter, benannter Formularfelder // (blocks[i][type], blocks[i][text] bzw. blocks[i][image]). Diese Felder werden // beim finalen Submit ganz normal vom Browser als multipart/form-data verschickt – // es ist kein manuelles Zusammenbauen von JSON beim Absenden mehr nötig. function addBlockElement(type, value = "") { const index = blockIndex++; const blockDiv = document.createElement("div"); blockDiv.classList.add("editor-block", "article-editor-scope"); blockDiv.setAttribute("data-index", String(index)); const typeInput = document.createElement("input"); typeInput.type = "hidden"; typeInput.name = `blocks[${index}][type]`; typeInput.value = type; blockDiv.appendChild(typeInput); if (type === "text") { const textarea = document.createElement("textarea"); textarea.name = `blocks[${index}][text]`; textarea.placeholder = "Schreibe deinen Textblock..."; textarea.value = value; blockDiv.appendChild(textarea); } else if (type === "image") { const fileInput = document.createElement("input"); fileInput.type = "file"; fileInput.name = `blocks[${index}][image]`; fileInput.accept = "image/*"; blockDiv.appendChild(fileInput); } const deleteBtn = document.createElement("button"); deleteBtn.type = "submit"; deleteBtn.name = "editor_action"; deleteBtn.value = `delete_block:${index}`; deleteBtn.classList.add("delete-block-btn"); deleteBtn.innerHTML = "✕"; blockDiv.appendChild(deleteBtn); container.appendChild(blockDiv); bindDeleteButton(blockDiv); bindImageInput(blockDiv); } // Löschen-Button eines Blocks lokal abfangen: entfernt den Block nur aus dem DOM, // statt das Formular zum Server zu senden. function bindDeleteButton(blockDiv) { const btn = blockDiv.querySelector(".delete-block-btn"); if (!btn) return; btn.addEventListener("click", (e) => { e.preventDefault(); blockDiv.remove(); }); } // Zeigt bei Auswahl einer Bilddatei sofort eine Vorschau an. Rein optisch – // der eigentliche Datei-Upload läuft nativ über das . function bindImageInput(blockDiv) { const fileInput = blockDiv.querySelector('input[type="file"]'); if (!fileInput) return; let imgPreview = blockDiv.querySelector(".block-image-preview"); if (!imgPreview) { imgPreview = document.createElement("img"); imgPreview.classList.add("block-image-preview"); imgPreview.style.maxWidth = "200px"; imgPreview.style.display = "none"; imgPreview.style.marginTop = "10px"; blockDiv.insertBefore(imgPreview, fileInput.nextSibling); } fileInput.addEventListener("change", function () { if (this.files && this.files[0]) { const reader = new FileReader(); reader.onload = (e) => { imgPreview.src = e.target.result; imgPreview.style.display = "block"; }; reader.readAsDataURL(this.files[0]); } }); } } // SICHERER START: Prüft, ob das HTML bereits bereit ist if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initEditor); } else { // Falls das DOM schon fertig geladen ist, führen wir es direkt aus initEditor(); }