Офис НП AMWAY в Ярославле
Купить продукцию Амвей в Ярославле
На карте Купить AMWAY в ЯрославлеПриобрести высококачественную продукцию Амвей в Ярославле, получить консультации по бизнесу, заказать продукцию или получить заказ:
Адрес: улица Валентины Терешковой, дом 1 (Вход со двора)
Телефон: +7 (920) 112-00-91
Email: matyxho@mail.ru
Сайт: https://www.amway.ru/user/lebedem
Визитка: http://yar.meweb.ru
Иерархия статей
Статьи » Программирование » Ajax кнопки Like Dislike для статей
Сниппет
Несложная реализация кнопок Нравится / Не нравится для статей на вашем проекте с использованием JQuery + Ajax + PHP + Cookie. Иногда весьма полезно знать отношение пользователей к вашим статьям, и эти кнопки немного помогут нам в этом.
Ajax кнопки Like Dislike для статей
Опубликовал  Pisatel Добавлено  02-03-2015 11:51 02 Март 2015 11:51:03 10240  Прочтений 10240 Прочтений  4 Комментариев 4 Комментариев
 printer
Сегодня будем создавать ajax плюшку для наших статей в виде кнопок Like / Dislike (Нравится / Не нравится). Итак, начнем. По ходу кода буду давать небольшие комментарии. Для начала создаем таблицу в бд article_like, куда и будем заносить количество лайков / дислайков. Априори подразумевается, что у вас уже имеются статьи и у каждой из них есть свой уникальный id, который нам понадобится для идентификации (будет записываться в поле article_like_id. Структура создаваемой таблицы:

Код: SQL
    CREATE TABLE article_like (

like_id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,

like_article_id MEDIUMINT(8) UNSIGNED NOT NULL,

like_like INT(10) UNSIGNED NOT NULL,

like_dislike INT(10) UNSIGNED NOT NULL,

PRIMARY KEY (like_id)

) ENGINE=MyISAM;




Таблица создана. Далее — разметка и сам вывод. Для иконок я буду использовать шрифт Font Awesome: он, конечно, великоват немного, но смотрится в итоге весьма кошерно. Для удобства подключения создадим небольшой файл (чтобы не прописывать лишний раз подключение к бд, плюс небольшая функция, взятая из cms PHP–Fusion для проверки числа), назовем его, например, config.php, и затем будем лишь вызывать на нужных страницах

Код: PHP
<?php

// создаем подключение к бд (данные вписываем свои)

$link = mysqli_connect("myhost", "myuser",

"mypass", "mydb") or die("Error ".mysqli_error($link));

// функция проверки числа

function isnum($value) {

if (!is_array($value)) {

return (preg_match("/^[0-9]+$/", $value));

} else {

return false;

}

}

?>




Теперь — подключение стиля и скриптов (размещаем на странице статьи)

Код: HTML5
<!-- подключаем файл стилей и файл js (последний можно подключить в подвал сайта

по умолчанию использую папку /inc/ для файлов, вы можете назвать ее как угодно -->

<head>

<link href='/like_dislike.css' rel='stylesheet' />

<script src='inc/jquery_1.11_min.js'></script>

<script src='inc/like_dislike.js'></script>

</head>




Теперь сам скрипт, который вставляем так же на страницу со статьей

Код: PHP
// подключаем наш config.php

require_once "config.php";

// подключение к бд и выборка

// выборку делаем по конкретной статье, за это отвечает параметр $_GET['article_id'], который берем из адреса страницы

// например, адрес у нас такой meweb.ru/articles.php?article_id=65

if (isset($_GET['article_id']) && isnum($_GET['article_id'])) {

$lresult = mysqli_query($link, "SELECT like_like, like_dislike FROM article_like WHERE like_article_id='".$_GET['article_id']."' LIMIT 1");

if (mysqli_num_rows($lresult)>0) {

// если получен корректный ответ- создаем массив и задаем значение переменных

$ldata = mysqli_fetch_assoc($lresult);

$like = $ldata['like_like'];

$unlike = $ldata['like_dislike'];

} else {

// иначе- записываем для данной статьи значения 0 и 0 для лайков и дислайков

mysqli_query($link, "INSERT INTO article_like (like_article_id, like_like, like_dislike) VALUES ('".$_GET['article_id']."', '0', '0')");

$like = "0";

$unlike = "0";

}

// теперь пошла сама разметка и вывод информации о количестве

$lres = "<div class='tbl tbl-border ldapo'>";

$lres .= "<div class='ldap'><i class='fa fa-line-chart'></i> Понравилась статья?</div>";

$lres .= "<div class='ld-stats-bar'></div>";

$lres .= "<span id='status'></span>";

$lres .= "<div class='ldapb'>";

$lres .= "<i class='fa fa-2x fa-thumbs-o-up'></i><input type='button' value='".$like."' class='button_like' id='linkeBtn' data-articleid='".$_GET['article_id']."' />";

$lres .= "<i class='fa fa-2x fa-thumbs-o-down'></i><input type='button' value='".$unlike."' class='button_unlike' id='unlinkeBtn' data-articleid='".$_GET['article_id']."' />";

$lres .= "</div></div>";

echo $lres;

// очищаем результат и закрываем подключение к бд

mysqli_free_result($lresult);

mysqli_close($link);

}




Теперь мы создадим файл like_dislike.js, которым будем перехватывать событие click по кнопке с идентификаторами linkeBtn и unlinkeBtn соответственно и отсылать/принимать данные на сервер/с севера посредством технологии Ajax. Как всегда, буду давать комментарии по ходу

Код: JQUERY
        $(function() {

// для начала убираем атрибуты disabled у наших кнопок input (если они существуют)

$('#linkeBtn').removeAttr('disabled');

$('#unlinkeBtn').removeAttr('disabled');

// создаем массив уведомлений для удобства

var Locale = {

alike: 'Статья понравилась!',

adislike: 'Статья не понравилась!',

atime: 'Вы уже оставили отзыв. Попробуйте позже.',

aerr: 'Произошла неизвестная ошибка.'

};

// берем значение val с кнопок

var l_val = parseInt($('#linkeBtn').val(), 10);

var d_val = parseInt($('#unlinkeBtn').val(), 10);

// задаем немного переменных для последующей работы с ними

var like = 'like';

var dislike = 'dislike';

var n_total = l_val + d_val;

var w_like;

var w_dislike;

var st;

var stn;

var div_n = '<div class=\'ld-bar-none\'></div>';

var div_l = '<div class=\'ld-bar-like\' style=\'width:100%;\'></div>';

var div_d = '<div class=\'ld-bar-dislike\' style=\'width:100%;\'></div>';

if (n_total == 0) {

// если сумма значений двух кнопок равна 0 (никто еще не голосовал)

// выводим соответствующий див

st = div_n;

} else if (d_val == 0 && l_val > 0) {

// иначе, если есть лайки, но нет дислайков

// красим див зеленым на 100%

st = div_l;

} else if (l_val == 0 && d_val > 0) {

// иначе, если есть дислайки, а лайков 0

// красим див полностью красным

st = div_d;

} else {

// иначе, если есть и лайки, и дислайки, производим их подсчет

// в процентном соотношении друг к другу

// и красим дивы зеленым/красным в процентном соотношении лайков/дислайков к 100%

w_like = Math.round(Math.abs(l_val * 100 / n_total));

w_dislike = 100 - w_like;

st = '<div class=\'ld-bar-like\' style=\'width:'+w_like+'%;\'></div><div class=\'ld-bar-dislike\' style=\'width:'+w_dislike+'%;\'></div>';

}

// выводим все, что сделали

$('.ld-stats-bar').append(st);



$('#linkeBtn').click(function(e) {

// если пользователю понравилась статья и он кликнул на кнопку

// перехватываем и обрабатываем событие

// взяли и запомнили id статьи

var article_id = $(this).data('articleid');

// добавим атрибут disabled для кнопки

// чтобы исключить повторное нажатие

$(this).attr('disabled', 'disabled');

// отсылаем ajax-запрос на сервер

$.ajax({

url:'/inc/like_dislike_ajax.php',

type:'POST', // метод выбираем post, так надежнее

data:({'article_id': article_id, 'like': like}), // передаем ид статьи и статус (лайк)

// функция обработки удачного ответа сервера

success: function(data) {

if (data==1) {

// если ответ равен 1

$('.ld-stats-bar').fadeOut('fast').empty(); // скрываем и очищаем див текущего статуса

l_val = l_val+1; // добавили единицу к val кнопки

n_total = n_total+1; // добавили 1 голос к общему количеству

if (l_val > 0 && d_val == 0) {

// если есть лайки, но нет дислайков, красим в зеленый

stn = div_l;

} else {

// иначе- вычисляем процентное соотношение

w_like = Math.round(Math.abs(l_val * 100 / n_total));

w_dislike = 100 - w_like;

stn = '<div class=\'ld-bar-like\' style=\'width:'+w_like+'%;\'></div><div class=\'ld-bar-dislike\' style=\'width:'+w_dislike+'%;\'></div>';

}

// выводим статус-сообщение об успешно добавленном голосе

$('#status').html('<i class=\'fa fa-check-square-o\'></i> '+Locale.alike).css({'color': '#006400'}).fadeIn('slow', function() {

setTimeout(function() { // статус-сообщение исчезнет через 5 секунд

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').append(stn).delay(300); // и появится обновленная полоса рейтинга с задержкой в 300 мс

}, 5000);

});

$('#linkeBtn').val(l_val).css({'color':'#222'}); // обновим value у кнопки, добавив 1 голос

} else {

// иначе, если ответ от сервера не равен 1

$('.ld-stats-bar').fadeOut('fast'); // убираем полосу рейтинга

// выводим статус-сообщение о том, что пользователь уже голосовал

$('#status').html('<i class=\'fa fa-lock\'></i> '+Locale.atime).css({'color': '#880000'}).fadeIn('slow', function() { // сообщение исчезнет через 4 секунды

setTimeout(function() {

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').delay(300); // возвращаем полосу рейтинга без обновления с задержкой в 300 мс

}, 4000);

});

}

},

// если во время запроса произошел какой-либо сбой, обрабатываем ошибку

error: function() {

$('.ld-stats-bar').fadeOut('fast'); // убираем полосу рейтинга

$('#status').html('<i class=\'fa fa-exclamation-triangle\'></i> '+Locale.aerr).css({'color': '#d00000'}).fadeIn('slow', function() {

setTimeout(function() {

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').delay(300);

}, 4000); // через 4 секунды убираем статус-сообщение и показываем шкалу рейтинга

});

$('#linkeBtn').removeAttr('disabled').delay(3000); // убираем атрибут disabled

}

});

});

// далее всё то же самое, но с кнопкой дислайк

$('#unlinkeBtn').click(function(e) {

$(this).attr('disabled', 'disabled');

var article_id = $(this).data('articleid');

$.ajax({

url:'/inc/like_dislike_ajax.php',

type:'POST',

data:({'article_id': article_id, 'dislike': dislike}),

success: function(data) {

if (data==1) {

$('.ld-stats-bar').fadeOut('fast').empty();

d_val = d_val+1;

n_total = n_total+1;

if (d_val > 0 && l_val == 0) {

stn = div_d;

} else {

w_dislike = Math.round(Math.abs(d_val * 100 / n_total));

w_like = 100 - w_dislike;

stn = '<div class=\'ld-bar-like\' style=\'width:'+w_like+'%;\'></div><div class=\'ld-bar-dislike\' style=\'width:'+w_dislike+'%;\'></div>';

}

$('#status').html('<i class=\'fa fa-check-square-o\'></i> '+Locale.adislike).css({'color': '#d00000'}).fadeIn('slow', function() {

setTimeout(function() {

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').append(stn).delay(300);

}, 5000);

});

$('#unlinkeBtn').val(d_val).css({'color':'#222'});

} else {

$('.ld-stats-bar').fadeOut('fast');

$('#status').html('<i class=\'fa fa-lock\'></i> '+Locale.atime).css({'color': '#880000'}).fadeIn('slow', function() {

setTimeout(function() {

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').delay(300);

}, 4000);

});

}

},

error: function() {

$('.ld-stats-bar').fadeOut('fast');

$('#status').html('<i class=\'fa fa-exclamation-triangle\'></i> '+Locale.aerr).css({'color': '#d00000'}).fadeIn('slow', function() {

setTimeout(function() {

$('#status').fadeOut('fast');

$('.ld-stats-bar').fadeIn('slow').delay(300);

}, 4000);

});

$('#unlinkeBtn').removeAttr('disabled').delay(3000);

}

});

});

});




Переходим к обработчику запроса. В папке inc создаем файл like_dislike_ajax.php с содержимым

Код: PHP
<?php

// подключаем config.php

require_once "../config.php";

// берем имя хоста для записи в cookie

$ldomain = htmlspecialchars($_SERVER['HTTP_HOST']);

// проверяем наличие post-запроса, и только после этого скрипт выполняется

if (isset($_POST['article_id']) && isnum($_POST['article_id']) && ((isset($_POST['like']) && $_POST['like'] == "like") || (isset($_POST['dislike']) && $_POST['dislike'] == "dislike"))) {

// проверяем, если cookie отсутствует- создаем

if (!isset($_COOKIE["counter_like_".$_POST['article_id']])) {

// записываем в куки время хранения- 1 сутки

setcookie("counter_like_".$_POST['article_id'], "liked", time()+3600*24, "/", $ldomain);

// если статья понравилась

if (isset($_POST['like']) && $_POST['like'] == "like") {

// прибавляем один лайк в бд

$update = "like_like=like_like+1";

} elseif (isset($_POST['dislike']) && $_POST['dislike'] == "dislike") {

// если не понравилась- прибавляем один дислайк

$update = "like_dislike=like_dislike+1";

}

// обновляем запись в базе

mysqli_query($link, "UPDATE article_like SET ".$update." WHERE like_article_id='".$_POST['article_id']."'");

$exit = 1;

// отдаем ответ скрипту like_dislike.js равный 1

echo json_encode($exit);

// закрываем соединение

mysqli_close($link);

} else {

// если файл cookie уже есть и сутки еще не прошли- отдаем ответ равный 2 (любой)

$exit = 2;

echo json_encode($exit);

exit;

}

// если в запросе нет post-данных или произошла ошибка

// при проверке ид статьи на целое число- убиваем выполнение скрипта

} else { die("Access Denied!"); }

?>




Ну и последний (но далеко не маловажный) штрих — это стиль. Ниже будет дизайн самих кнопок, полосы статуса и статус–сообщений. Однако, это не все. Чуть ниже расскажу, как и куда это чудо дизайнерской мысли добавить.

Код: CSS
.tbl-border {

border: 1px solid #ccc;

border-radius: 5px;

}

.tbl {

font-size: 11px;

padding: 4px;

}

.button_like, .button_unlike {

border: none;

height: 32px;

padding-left: 40px;

vertical-align: middle;

background-color: #f3f3f3;

background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f3f3f3), color-stop(50%, #ddd), color-stop(50%, #d2d2d2), color-stop(100%, #dfdfdf));

background-image: -webkit-linear-gradient(top, #f3f3f3 0%, #ddd 50%, #d2d2d2 50%, #dfdfdf 100%);

background-image: -moz-linear-gradient(top, #f3f3f3 0%, #ddd 50%, #d2d2d2 50%, #dfdfdf 100%);

background-image: -o-linear-gradient(top, #f3f3f3 0%, #ddd 50%, #d2d2d2 50%, #dfdfdf 100%);

background-image: linear-gradient(top, #f3f3f3 0%, #ddd 50%, #d2d2d2 50%, #dfdfdf 100%);

border-right: 1px solid #dfdfdf;

border-bottom: 1px solid #b4b4b4;

border-radius: 5px;

-webkit-box-shadow: inset 0 1px 0 0 #fff, 0 1px 0 0 #d5d5d5, 0 -1px 2px 1px #efefef;

box-shadow: inset 0 1px 0 0 #fff, 0 1px 0 0 #d5d5d5, 0 -1px 2px 1px #efefef;

font: bolder 16px/1 "helvetica neue", helvetica, arial, sans-serif;

margin: 0;

text-shadow: 0 1px 1px #fff;

}

.button_like {

color: hsl(120, 25%, 50%);

}

.button_unlike {

color: hsl(0, 100%, 42%);

}

.button_like:hover, .button_unlike:hover {

background-color: #e5e5e5;

background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #e5e5e5), color-stop(50%, #d1d1d1), color-stop(50%, #c4c4c4), color-stop(100%, #b8b8b8));

background-image: -webkit-linear-gradient(top, #e5e5e5 0%, #d1d1d1 50%, #c4c4c4 50%, #b8b8b8 100%);

background-image: -moz-linear-gradient(top, #e5e5e5 0%, #d1d1d1 50%, #c4c4c4 50%, #b8b8b8 100%);

background-image: -o-linear-gradient(top, #e5e5e5 0%, #d1d1d1 50%, #c4c4c4 50%, #b8b8b8 100%);

background-image: linear-gradient(top, #e5e5e5 0%, #d1d1d1 50%, #c4c4c4 50%, #b8b8b8 100%);

-webkit-box-shadow: inset 0 1px 0 0 #f2f2f2, 0 1px 0 0 #c9c9c9, 0 -1px 2px 1px #e3e3e3;

box-shadow: inset 0 1px 0 0 #f2f2f2, 0 1px 0 0 #c9c9c9, 0 -1px 2px 1px #e3e3e3;

cursor: pointer;

}

.button_like:active, .button_unlike:active {

-webkit-box-shadow: inset 0 0 30px 0 #999, 0 1px 0 0 #fff;

box-shadow: inset 0 0 30px 0 #999, 0 1px 0 0 #fff;

}

.ldapo {

position: relative;

height: 34px;

margin: 5px 0;

}

.ldap {

font-size: 16px;

font-weight: bolder;

position: absolute;

left: 7px;

top: 13px;

vertical-align: middle;

text-shadow: 0 1px 0 #fff;

}

.ldapb {

display: inline;

text-align: right;

position: absolute;

right: 7px;

top: 6px;

vertical-align: middle;

}

.ldapb i.fa-thumbs-o-up, .ldapb i.fa-thumbs-o-down {

position: relative;

left: 26px;

top: 6px;

}

.ldapb i.fa-thumbs-o-up {

color: #008000;

}

.ldapb i.fa-thumbs-o-down {

color: #d00000;

}

.ldapo span {

position: absolute;

right: 25%;

top: 13px;

font-size: 14px;

font-weight: bold;

text-align: right;

}

.ld-stats-bar {

position: absolute;

right: 25%;

top: 19px;

height: 5px;

width: 330px;

font-size: 0;

line-height: 0;

border: 1px solid #c5c5c5;

-webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, .25);

-moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, .25);

-o-box-shadow: 2px 2px 5px rgba(0, 0, 0, 25);

box-shadow: 2px 2px 5px rgba(0, 0, 0, .25);

background-color: #fff;

}

.ld-bar-like, .ld-bar-dislike, .ld-bar-none {

margin: 0;

height: 5px;

font-size: 0;

line-height: 0;

border: 0;

padding: 0;

outline: none;

}

.ld-bar-like {

float: left;

background-color: #008000;

}

.ld-bar-dislike {

float: right;

background-color: #d00000;

}

.ld-bar-none {

width: 100%;

background: -webkit-repeating-linear-gradient(-45deg, #f9f9f9, #f9f9f9 10px, #ccc 10px, #ccc 20px);

background: -moz-repeating-linear-gradient(-45deg, #f9f9f9, #f9f9f9 10px, #ccc 10px, #ccc 20px);

background: -o-repeating-linear-gradient(-45deg, #f9f9f9, #f9f9f9 10px, #ccc 10px, #ccc 20px);

background: repeating-linear-gradient(-45deg, #f9f9f9, #f9f9f9 10px, #ccc 10px, #ccc 20px);

}




Ну а далее — немного гемороя. Попробую объяснить подробнее. Качаем шрифт Font Awesome (на момент выхода статьи текущая версия 4.3.0), распаковываем шрифты по пути /inc/fonts/, берем файл font-awesome.min.css и переименовываем его в like_dislike.css, кидаем в папку /inc/, предварительно чуть изменив: в самый конец файла добавить тот стиль, что дан выше, плюс поменять в начале файла пути до шрифтов, заменив ../fonts/ на fonts/.

Что ж, похоже, на этом все. Лицезреть пример вы можете сразу под статьей. Будут вопросы — спрашиваем в комментариях. Всем всех благ и удачи во всех начинаниях.
Понравилась статья?
Метки для данной статьи
Похожие статьи
Поделиться:   
Комментарии
#1 | drift 16 декабря 2015 03:18:35
No Avatar
Гость
Здравствуйте! Смотрю у вас много вариантов с Ajax. Не думали создать плагин Social Locker с использованием Ajax ? Чтобы скрыть часть статьи-новости и ткрыть после того как пользователь поделится ссылкой в соц сетях Вконтакте Одноклассники и тд. В интернете много разных вариантов но все они без ajax и скрытый контент (у меня это ссылки) виден через просмот Html кода страницы. Было бы здорво иметь такой плагин для PHP-Fusion.
#2 | Pisatel 16 декабря 2015 09:11:31
Avatar
Отсутствует
Супер Администратор
Активный
С 03. февраля 2013
Здравствуйте. Сейчас не до этого, к сожалению: пишу каталог продукции, почти закончил. Может, чуть позже))
Я не европеец. И не азиат. Я русский. Я россиянин. Я за истинные семейные христианские ценности. И это - моя национальная идея.
#3 | racaMn 21 февраля 2019 06:36:38
No Avatar
Гость
можно было бы и без мата..

---
Мне кажется, что это уже обсуждалось. скачать fifa 15 pc 32 bit, fifa 15 rus скачать и скачать fifa 15 c таблеткой fifa 15 new season скачать
#4 | ripptwenZef 24 февраля 2019 11:39:57
No Avatar
Гость
как мило.))

---
Мне кажется это блестящая фраза скачать fifa 15 через медиа гет, fifa 15 скачать торрент pc без таблетки и скачать fifa 15 карьера скачать составы для fifa 15 сезон 2017
Добавить комментарий
Имя:

Проверочный код:
Последние активные темы форума
  Темы Просмотров Ответов Последние сообщения
folder Плагин Email рассылки Mail To All by Pisatel
CMS PHP Fusion
13258 33 promask
27. апреля 2019
folder Вопрос по переделке bb-кода
PHP, MySQL
3332 5 Pisatel
26. мая 2017
folder Вопросы по Ajax форме обратной связи
CMS PHP Fusion
13801 48 Ditrin
19. февраля 2017
folder BBCode YouTube Video Colorbox mod
CMS PHP Fusion
7707 2 Pisatel
10. декабря 2016
folder Как лучше создать собственную страницу?
CMS PHP Fusion
7056 17 Pisatel
11. мая 2016
folder Небольшие вопросы по скриптам магазина и катало...
PHP, MySQL
52717 80 Pisatel
11. января 2016
folder BBCode Code mod
CMS PHP Fusion
4027 0 Pisatel
31. августа 2015
folder Ajax Like Dislike Article Panel
CMS PHP Fusion
8160 16 Pisatel
07. июля 2015
folder Хлебные крошки / BreadCrumbs SEO Panel
CMS PHP Fusion
9200 17 Pisatel
04. июля 2015
folder Abbr Description BBCode
CMS PHP Fusion
3042 0 Pisatel
15. июня 2015
folder Подозрительный трафик и прочие страшилки
Всякая хрень
5705 2 Ditrin
23. апреля 2015
folder Мод Newsletter - рассылка писем пользователям с...
CMS PHP Fusion
7728 13 Pisatel
10. апреля 2015
folder Мод отправки писем PHPMailer для PHP-Fusion
CMS PHP Fusion
41279 113 Ditrin
06. апреля 2015
folder Появление неизвестного файла subscriptions.php
CMS PHP Fusion
3721 2 Pisatel
06. апреля 2015
folder Autoban on IP
CMS PHP Fusion
13635 13 Pisatel
03. апреля 2015