// Необходим jQuery
// Вот так используется:
// Для использования токена необходимо его задание через небольшой inline-скрипт:
//
// Использует подсистему тоста и функцию показа сообщения в тосте
// Эта система должна присутвовать на странице показа
$(document).ready(function () {
initializeVotingPanels();
$(document).on("click", ".sl-user-interaction .sl-like, .sl-user-interaction .sl-dislike", function (e) {
e.preventDefault();
// ищем родительский контроллер с данными
var $container = $(this).closest(".sl-user-interaction");
var contentType = $container.data("content-type");
var contentId = $container.data("content-id");
const csrf_token = window.csrf_token;
// определяем значение голоса
var $votingElement = $container.find(".sl-voting");
var currentVote = parseInt($votingElement.data("user-vote"), 10) || 0;
var newVote = $(this).hasClass("sl-like") ? 1 : -1;
// Если клик совпадает с текущим, снимаем его (делаем 0)
if (newVote === currentVote) { newVote = 0; }
// alert('Current ' + currentVote);
// alert('New ' + newVote);
// запрос на сервер
$.ajax({
url: "user-interaction.vote",
method: "POST",
// dataType: "json",
data: {
csrf_token: csrf_token,
content_type: contentType,
content_id: contentId,
vote: newVote,
},
success: function (response) {
// console.log(response);
if (response.hasError) {
showToast(response.message, "danger");
return;
}
// предпологается что от сервера возращается общее количество лайков и дизлайков, а также новое значение для пользователя
newVote = response.data.user_vote;
newLikes = response.data.likes;
newDislikes = response.data.dislikes;
// alert('New From Server ' + newVote);
// сохраняем новое значение (и в jquery кэше и в html)
$votingElement.data("user-vote", newVote).attr("data-user-vote", newVote);
// обновляем внешний вид кнопок
$container.find(".sl-like, .sl-dislike").removeClass("active");
if (newVote === 1) {
$container.find(".sl-like").addClass("active");
}
else if (newVote === -1) {
$container.find(".sl-dislike").addClass("active");
}
// обновляем общее количество
$container.find(".sl-like .sl-value").text(newLikes);
$container.find(".sl-dislike .sl-value").text(newDislikes);
showToast("Голос успешно обновлён: " + newVote, "success");
},
error: function (jqXHR, textStatus, errorThrown) {
console.error("AJAX Error:", textStatus, errorThrown); // Логируем текст ошибки
showToast("Ошибка! Не удалось выполнить голосование.", "danger");
}
}); // END of $ajax({
}); // END of $(document).on("click", ".sl-user-interaction .sl-like, .sl-user-interaction .sl-dislike", function (e)
}); // END of $(document).ready(function ()
/**
* Функция для инициализации всех элементов голосования.
* Проверяет флаг `data-loaded`, и если элемент не загружен, делает AJAX-запрос.
*/
function initializeVotingPanels() {
$(".sl-user-interaction .sl-voting").each(function () {
var $voting = $(this);
// Проверяем, загружены ли данные (data-loaded)
if ($voting.attr("data-loaded") === "1") {
return; // Уже загружено, пропускаем
}
var $container = $voting.closest(".sl-user-interaction");
var contentType = $container.data("content-type");
var contentId = $container.data("content-id");
var csrf_token = window.csrf_token; // Глобальная переменная с CSRF-токеном
$.ajax({
url: "user-interaction.vote-init",
method: "POST",
data: {
csrf_token: csrf_token,
content_type: contentType,
content_id: contentId
},
success: function (response) {
// если ошибка, все подробности в консоле, ничего другого не делать
if (response.hasError) {
// элемент остается неактивированным // old: // $voting.attr("data-loaded", "error");
console.error("Ошибка загрузки голосов:", response.message);
return;
}
var userVote = response.data.user_vote;
var likes = response.data.likes;
var dislikes = response.data.dislikes;
// Устанавливаем данные в HTML
$voting.data("user-vote", userVote).attr("data-user-vote", userVote);
$voting.attr("data-loaded", "1");
var likeButton = $container.find(".sl-like");
var dislikeButton = $container.find(".sl-dislike");
likeButton.find(".sl-value").text(likes);
dislikeButton.find(".sl-value").text(dislikes);
likeButton.removeClass("active");
dislikeButton.removeClass("active");
//
if (userVote === 1) {
likeButton.addClass("active");
} else if (userVote === -1) {
dislikeButton.addClass("active");
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.error("Ошибка AJAX при загрузке голосов:", textStatus, errorThrown);
}
});
});
}