Ajax лайки/дизлайки для записей

Ajax лайки и дизлайки для записейВ этой статье я приведу пример создания лайков и дизлайков для новостей. Голосование будет работать без перезагрузки страницы, за счет использования технологии передачи данных на сервер — ajax. Для работы примера необходимо подключить библиотеку jQuery. Начнем.
Для начала создадим таблицы в базе данных. Их будет три. Одна для хранения тестовых новостей, вторая для тестовых пользователей и третья для связи пользователей с голосами.

С таблицами для новостей и пользователь все ясно, тут нет смысла что-то описывать. Интерес представляет третья таблица, для хранения связи пользователя и голоса, назовем таблицу votes_news2user. Записывать в эту таблицу будем id пользователи и id новости, за которую пользователь голосовал. И при каждом голосе будем проверять по таблице votes_news2user голосовал пользователь раньше или нет.
Для создания всех нужных таблиц с тестовыми данными можете воспользоваться вот этим патчем:

-- Создание таблицы с новостями
CREATE TABLE IF NOT EXISTS `news` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `small_text` varchar(255) NOT NULL,
  `big_text` text NOT NULL,
  `date_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `is_active` tinyint(1) NOT NULL,
  `count_like` int(10) NOT NULL,
  `count_dislike` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- Заполнение таблицы с новостями
INSERT INTO `news` (`id`, `title`, `small_text`, `big_text`, `date_create`, `is_active`, `count_like`, `count_dislike`) VALUES
	(1, 'Новость 1', 'короткое описание 1', 'полный текст', '2014-01-18 17:36:02', 1, 0, 0),
	(2, 'Новость 2', 'короткое описание 2', 'полный текст', '2014-01-18 17:36:02', 1, 0, 0),
	(3, 'Новость 3', 'короткое описание 3', 'полный текст', '2014-01-18 17:36:25', 1, 0, 0),
	(4, 'Новость 4', 'короткое описание 4', 'полный текст', '2014-01-22 20:59:53', 1, 0, 0),
	(5, 'Новость 5', 'короткое описание 5', 'полный текст', '2014-01-22 20:59:52', 1, 0, 0);

-- Создание таблицы для пользователей
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `login` varchar(50) NOT NULL,
  `pass` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- Заполнение таблицы с пользователями
INSERT INTO `users` (`id`, `login`, `pass`) VALUES (1, 'test', 'pass');

-- Создание таблицы для связи пользователя и голоса за новость
CREATE TABLE IF NOT EXISTS `votes_news2user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `id_user` int(10) NOT NULL,
  `id_news` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

После того как база данных создана и заполнена, необходимо создать страницу для вывода новостей и с кнопками для голосования:

<style>
.one_news span {
    border: 1px dotted;
    cursor: pointer;
    display: block;
    margin-bottom: 5px;
    text-align: center;
    width: 85px;
}
.one_news span:hover{
	border: 1px solid;
}
</style>

<?php
// подключение к бд
include "db_connection.php";

$userId = 1; // id пользователя
// достаем все новости
$sql = mysql_query("
    SELECT * FROM `news`
") or die(mysql_error());    
$news = array();
while($r = mysql_fetch_array($sql, MYSQL_ASSOC)){
    $news[] = $r;
}
?>
<div>
	<input type="hidden" id="id_user" value="<?=$userId;?>" />
	<?php foreach($news as $oneNews){ ?>
	<div class="one_news">
		<h3><?=$oneNews['title'];?></h3>
		<p><?=$oneNews['title'];?></p>
		<span id="like">Like (<b><?=$oneNews['count_like'];?></b>)</span>
		<span id="dislike">DisLike (<b><?=$oneNews['count_dislike'];?></b>)</span>
		<input type="hidden" id="id_news" value="<?=$oneNews['id'];?>" />
	</div>
	<hr/>
	<?php } ?>
</div>

Код скрипта для подключения к базе данных храниться в файле db_connection.php. Вот его код:

define("HOST", "localhost");
define("USER", "root");
define("PASSWORD", "");
define("DB_NAME", "test_db");
$db_connect = mysql_connect(HOST, USER, PASSWORD, TRUE); 
mysql_selectdb(DB_NAME,$db_connect);
mysql_set_charset('utf8');

Теперь составим скрипт, который будет обрабатывать аякс запросы и если нужно, то делать записи в базу данных или выводить сообщения об ошибках. Назовем его ajax_test.php:

// подключение к бд
include "db_connection.php";

// контейнер для ошибок 
$error = false;
// получение данных
$userId = (int) $_POST['id_user'];
$newsId = (int) $_POST['id_news'];
$type = $_POST['type'];

// проверяем, голосовал ранее пользователь за эту новость или нет
$sql = mysql_query("
	SELECT count(*) FROM `votes_news2user` WHERE `id_user` = $userId AND `id_news` = $newsId
") or die(mysql_error()); 
$result = mysql_fetch_row($sql);
// если что-то пришло из запроса, значит уже голосовал
//var_dump($result);exit;
if($result[0] > 0){
	$error = 'Вы уже голосовали';
}else{ // если пользователь не голосовал, проголосуем
	// получем поле для голосования - лайк или дизлайк
	if($type == 'like') $fieldName = 'count_like'; 
	if($type == 'dislike') $fieldName = 'count_dislike';
	// делаем запись о том, что пользователь проголосовал
	mysql_query("
		INSERT INTO `votes_news2user` (`id_user`, `id_news`) VALUES ($userId, $newsId)
	") or die(mysql_error()); 
	// делаем запись для новости - увеличиваем количесво голосов(лайк или дизлайк)
	mysql_query("
		UPDATE `test_db`.`news` SET `$fieldName`= `$fieldName` + 1 WHERE  `id` = $newsId
	") or die(mysql_error());
}
	
// делаем ответ для клиента
if($error){
	// если есть ошибки то отправляем ошибку и ее текст
	echo json_encode(array('result' => 'error', 'msg' => $error));
}else{
	// если нет ошибок сообщаем об успехе
	echo json_encode(array('result' => 'success'));
}

Остается только написать javascript, который будет отправлять ajax запросы к скрипту ajax_test.php

$(document).ready(function() {
	$('span#like').click(function(){
		setVote('like', $(this));
	});
	
	$('span#dislike').click(function(){
		setVote('dislike', $(this));
	});
	
});

// type - тип голоса. Лайк или дизлайк
// element - кнопка, по которой кликнули
function setVote(type, element){
	// получение данных из полей
	var id_user = $('#id_user').val();
	var id_news = element.parent().find('#id_news').val();
	
	$.ajax({
		// метод отправки 
		type: "POST",
		// путь до скрипта-обработчика
		url: "/ajax_test.php",
		// какие данные будут переданы
		data: {
			'id_user': id_user, 
			'id_news': id_news,
			'type': type
		},
		// тип передачи данных
		dataType: "json",
		// действие, при ответе с сервера
		success: function(data){
			// в случае, когда пришло success. Отработало без ошибок
			if(data.result == 'success'){	
				// Выводим сообщение
				alert('Голос засчитан');
				// увеличим визуальный счетчик
				var count = parseInt(element.find('b').html());
				element.find('b').html(count+1);
			}else{
				// вывод сообщения об ошибке
				alert(data.msg);
			}
		}
	});
}

Вот и все, на этом создание ajax лайков закончено. Скрипт и дамп базы данных вы можете скачать в архиве вот тут.

Рассказать друзьям:


Оценить:
(84 оценок, среднее: 4,01 из 5)

Ajax лайки/дизлайки для записей: 7 комментариев

  1. Очень интересное решение, спасибо Вам большое. Подскажите пожалуйста, как можна использовать данный скрипт, если на странице не один элемент Like/Dislike т.е. на странице список где в каждой строчке стоит элемент Like/Dislike? Пробовал так <span id="like-«>like () потом в ajax_test.php explode’ром получаю тип, но … не работает почему-то. Помогите пожалуйста.

    1. Здравствуйте! Вы можете в функцию setVote, добавить третий параметр — уникальный идентификатор элемента, за который пользователи будут голосовать. Получив в функции этот id, передавайте его аяксом на сервер и там уже по нему делайте запись в базу данных.

  2. Хммм. Например, если ввести в ПС гугл запрос «Добавляем рейтинг для google», появится выдача, в которой есть сайты, у которых в сниппете есть звёзды. Вот я испросил, будет ли у Вашего примера вывод в гугле такой же.

  3. Здравствуйте! Подскажите, пожалуйста, как отвязать скрипт от id пользователя. Запретить только, ставить лайки, например один раз в сутки.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

code