// Необходим 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); } }); }); }