/** * Initialisiert die Kommentarfunktion. * * Ermöglicht: * - Erstellen neuer Kommentare * - Antworten auf bestehende Kommentare * - AJAX-Kommunikation ohne Seitenneuladen */ document.addEventListener("DOMContentLoaded", function () { const form = document.getElementById("comment-form"); const commentsList = document.getElementById("comments-list"); const commentContent = document.getElementById("comment-content"); const parentCommentInput = document.getElementById("parent-comment-id"); const replyInfo = document.getElementById("reply-info"); if (!form || !commentsList || !commentContent || !parentCommentInput || !replyInfo) { return; } /** * Registriert die Antwort-Buttons. * * Beim Klick wird die ID des Eltern-Kommentars gespeichert, * damit die neue Nachricht als Antwort angelegt werden kann. */ document.querySelectorAll(".reply-button").forEach(function (button) { button.addEventListener("click", function () { parentCommentInput.value = button.dataset.commentId; replyInfo.textContent = "Antwort auf " + button.dataset.author; replyInfo.style.display = "block"; commentContent.focus(); }); }); /** * Verarbeitet das Absenden eines Kommentars. * * Die Daten werden per AJAX an den Server gesendet, * sodass die Seite nicht neu geladen werden muss. */ form.addEventListener("submit", function (event) { event.preventDefault(); const formData = new FormData(form); const parentCommentId = parentCommentInput.value; /* * Sendet den Kommentar an den Server * und speichert ihn in der Datenbank. */ fetch("php/ajax/add-comment.php", { method: "POST", body: formData }) .then(response => response.json()) .then(data => { if (!data.success) { alert(data.message); return; } const emptyMessage = commentsList.querySelector(".no-comments-message"); if (emptyMessage) { emptyMessage.remove(); } const commentElement = document.createElement("div"); commentElement.classList.add("comment-item"); if (parentCommentId) { commentElement.classList.add("comment-reply"); } commentElement.innerHTML = `

${escapeHtml(data.author)} ${escapeHtml(data.created)}

${escapeHtml(data.content).replace(/\n/g, "
")}

`; /* * Antworten werden unter dem * zugehörigen Kommentar angezeigt. */ if (parentCommentId) { const parentComment = document.querySelector( `.comment-item[data-comment-id="${parentCommentId}"] .comment-replies` ); if (parentComment) { parentComment.appendChild(commentElement); } } else { /* * Normale Kommentare werden * oben in die Liste eingefügt. */ commentElement.dataset.commentId = ""; commentsList.prepend(commentElement); } /* * Formular zurücksetzen. */ commentContent.value = ""; parentCommentInput.value = ""; replyInfo.textContent = ""; replyInfo.style.display = "none"; }) .catch(() => { alert( "Kommentar konnte nicht gesendet werden." ); }); }); /** * Escaped HTML-Sonderzeichen zur Vermeidung * von XSS-Angriffen. * * @param {string} text Zu bereinigender Text * @returns {string} HTML-sicherer Text */ function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } });