310 lines
8.7 KiB
JavaScript
310 lines
8.7 KiB
JavaScript
/**
|
|
* Initialisiert die Kommentarfunktion.
|
|
*
|
|
* Kommentare werden per AJAX gespeichert,
|
|
* ohne dass die Seite neu geladen werden muss.
|
|
*/
|
|
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) {
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Aktiviert einen einzelnen Antworten-Link.
|
|
*
|
|
* @param {HTMLAnchorElement} replyLink Antworten-Link
|
|
*/
|
|
function registerReplyButton(replyLink) {
|
|
replyLink.addEventListener("click", function (event) {
|
|
/*
|
|
* Mit JavaScript wird die Seite nicht neu geladen.
|
|
* Ohne JavaScript funktioniert der normale Link.
|
|
*/
|
|
event.preventDefault();
|
|
|
|
parentCommentInput.value = replyLink.dataset.commentId;
|
|
|
|
if (replyInfo) {
|
|
replyInfo.textContent =
|
|
"Antwort auf " + replyLink.dataset.author;
|
|
replyInfo.style.display = "block";
|
|
}
|
|
|
|
commentContent.focus();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Registriert alle bereits vorhandenen Antwort-Buttons.
|
|
*/
|
|
document.querySelectorAll(".reply-button").forEach(function (button) {
|
|
registerReplyButton(button);
|
|
});
|
|
|
|
/**
|
|
* Sendet Kommentare per AJAX an den Server.
|
|
*/
|
|
form.addEventListener("submit", function (event) {
|
|
event.preventDefault();
|
|
|
|
const formData = new FormData(form);
|
|
const parentCommentId = parentCommentInput.value;
|
|
|
|
fetch(form.action, {
|
|
method: "POST",
|
|
body: formData,
|
|
headers: {
|
|
"X-Requested-With": "XMLHttpRequest"
|
|
}
|
|
})
|
|
.then(function (response) {
|
|
if (!response.ok) {
|
|
throw new Error("Fehlerhafte Serverantwort.");
|
|
}
|
|
|
|
return response.json();
|
|
})
|
|
.then(function (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");
|
|
commentElement.dataset.commentId = data.commentId;
|
|
|
|
if (parentCommentId !== "") {
|
|
commentElement.classList.add("comment-reply");
|
|
|
|
commentElement.innerHTML = `
|
|
<p>
|
|
<strong>${escapeHtml(data.author)}</strong>
|
|
<span>${escapeHtml(data.created)}</span>
|
|
</p>
|
|
|
|
<p>${escapeHtml(data.content).replace(/\n/g, "<br>")}</p>
|
|
|
|
<details class="edit-comment-details">
|
|
<summary class="edit-comment-button">
|
|
Antwort bearbeiten
|
|
</summary>
|
|
|
|
<form
|
|
method="post"
|
|
action="index.php?pfad=updateComment"
|
|
class="edit-comment-form"
|
|
>
|
|
<input
|
|
type="hidden"
|
|
name="csrf_token"
|
|
value="${escapeHtml(formData.get("csrf_token"))}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="comment_id"
|
|
value="${escapeHtml(data.commentId)}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="article_id"
|
|
value="${escapeHtml(formData.get("article_id"))}"
|
|
>
|
|
|
|
<textarea
|
|
name="content"
|
|
required
|
|
>${escapeHtml(data.content)}</textarea>
|
|
|
|
<button type="submit" class="button">
|
|
Änderungen speichern
|
|
</button>
|
|
</form>
|
|
</details>
|
|
|
|
<form
|
|
method="post"
|
|
action="index.php?pfad=deleteComment"
|
|
class="delete-comment-form"
|
|
>
|
|
<input
|
|
type="hidden"
|
|
name="csrf_token"
|
|
value="${escapeHtml(formData.get("csrf_token"))}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="comment_id"
|
|
value="${escapeHtml(data.commentId)}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="article_id"
|
|
value="${escapeHtml(formData.get("article_id"))}"
|
|
>
|
|
|
|
<button
|
|
type="submit"
|
|
class="delete-comment-button"
|
|
onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');"
|
|
>
|
|
Kommentar löschen
|
|
</button>
|
|
</form>
|
|
`;
|
|
|
|
const parentReplies = commentsList.querySelector(
|
|
`.comment-item[data-comment-id="${parentCommentId}"] .comment-replies`
|
|
);
|
|
|
|
if (parentReplies) {
|
|
parentReplies.appendChild(commentElement);
|
|
} else {
|
|
commentsList.prepend(commentElement);
|
|
}
|
|
} else {
|
|
commentElement.innerHTML = `
|
|
<p>
|
|
<strong>${escapeHtml(data.author)}</strong>
|
|
<span>${escapeHtml(data.created)}</span>
|
|
</p>
|
|
|
|
<p>${escapeHtml(data.content).replace(/\n/g, "<br>")}</p>
|
|
|
|
<details class="edit-comment-details">
|
|
<summary class="edit-comment-button">
|
|
Kommentar bearbeiten
|
|
</summary>
|
|
|
|
<form
|
|
method="post"
|
|
action="index.php?pfad=updateComment"
|
|
class="edit-comment-form"
|
|
>
|
|
<input
|
|
type="hidden"
|
|
name="csrf_token"
|
|
value="${escapeHtml(formData.get("csrf_token"))}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="comment_id"
|
|
value="${escapeHtml(data.commentId)}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="article_id"
|
|
value="${escapeHtml(formData.get("article_id"))}"
|
|
>
|
|
|
|
<textarea
|
|
name="content"
|
|
required
|
|
>${escapeHtml(data.content)}</textarea>
|
|
|
|
<button type="submit" class="button">
|
|
Änderungen speichern
|
|
</button>
|
|
</form>
|
|
</details>
|
|
|
|
<form
|
|
method="post"
|
|
action="index.php?pfad=deleteComment"
|
|
class="delete-comment-form"
|
|
>
|
|
<input
|
|
type="hidden"
|
|
name="csrf_token"
|
|
value="${escapeHtml(formData.get("csrf_token"))}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="comment_id"
|
|
value="${escapeHtml(data.commentId)}"
|
|
>
|
|
|
|
<input
|
|
type="hidden"
|
|
name="article_id"
|
|
value="${escapeHtml(formData.get("article_id"))}"
|
|
>
|
|
|
|
<button
|
|
type="submit"
|
|
class="delete-comment-button"
|
|
onclick="return confirm('Möchtest du diesen Kommentar wirklich löschen?');"
|
|
>
|
|
Kommentar löschen
|
|
</button>
|
|
</form>
|
|
|
|
<a
|
|
href="#comment-form"
|
|
class="reply-button"
|
|
data-comment-id="${escapeHtml(data.commentId)}"
|
|
data-author="${escapeHtml(data.author)}"
|
|
>
|
|
Antworten
|
|
</a>
|
|
|
|
<div class="comment-replies"></div>
|
|
`;
|
|
|
|
commentsList.prepend(commentElement);
|
|
|
|
const newReplyButton =
|
|
commentElement.querySelector(".reply-button");
|
|
|
|
if (newReplyButton) {
|
|
registerReplyButton(newReplyButton);
|
|
}
|
|
}
|
|
|
|
commentContent.value = "";
|
|
parentCommentInput.value = "";
|
|
|
|
if (replyInfo) {
|
|
replyInfo.textContent = "";
|
|
replyInfo.style.display = "none";
|
|
}
|
|
})
|
|
.catch(function (error) {
|
|
console.error(error);
|
|
alert("Kommentar konnte nicht gesendet werden.");
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Entfernt HTML-Sonderzeichen aus Nutzereingaben.
|
|
*
|
|
* @param {*} text Zu bereinigender Text
|
|
* @returns {string} Sicherer Text
|
|
*/
|
|
function escapeHtml(text) {
|
|
const div = document.createElement("div");
|
|
div.textContent = String(text ?? "");
|
|
return div.innerHTML;
|
|
}
|
|
}); |