Сегодня я подготовил новый интересный урок — мы создадим собственную систему Poll (AJAX) для ваших проектов на PHP. Опросы, ответы и результаты я собираюсь сохранить в единой SQL-таблице. Когда мы будем голосовать за один из вариантов — jQuery будет POST-данные, а затем мы будем анимировать наши результаты в реальном времени.
Live Demo
скачать в упаковке
Теперь загрузите исходные файлы и начните кодировать!
Шаг 1. SQL
Нам нужно будет добавить одну таблицу в нашу базу данных:
CREATE TABLE `s183_polls` ( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) default '', `answers` text NOT NULL, `results` varchar(60) NOT NULL default '', `total_votes` int(10) NOT NULL default '0', `when` int(10) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `s183_polls` (`id`, `title`, `answers`, `results`, `total_votes`, `when`) VALUES (NULL, 'First poll question', 'Answer 1<sep>Answer 2<sep>Answer 3<sep>Answer 4', '', 0, UNIX_TIMESTAMP()), (NULL, 'Second poll question', 'Answer 21<sep>Answer 22<sep>Answer 23<sep>Answer 24', '', 0, UNIX_TIMESTAMP()+1), (NULL, 'Third poll question', 'Answer 31<sep>Answer 32<sep>Answer 33<sep>Answer 34', '', 0, UNIX_TIMESTAMP()+2), (NULL, 'Forth poll question', 'Answer 41<sep>Answer 42<sep>Answer 43<sep>Answer 44', '', 0, UNIX_TIMESTAMP()+3), (NULL, 'Fifth poll question', 'Answer 51<sep>Answer 52<sep>Answer 53<sep>Answer 54', '', 0, UNIX_TIMESTAMP()+4);
Это основная таблица опросов.
Шаг 2. PHP
Вот исходный код нашего основного файла:
index.php
<?php
// disable warnings
if (version_compare(phpversion(), "5.3.0", ">=") == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);
require_once('classes/CMySQL.php'); // including service class to work with database
if ($_POST['do'] == 'vote') { // in case if we submitted poll
$iPollId = (int)$_POST['id'];
$iAnswer = (int)$_POST['answer'];
if ($iPollId && $iAnswer >= 0 && ! isset($_COOKIE['av' . $iPollId])) {
// get poll info
$aPollInfo = $GLOBALS['MySQL']->getRow("SELECT * FROM `s183_polls` WHERE `id` = '{$iPollId}'");
// updating of poll results
$aAnswers = explode('<sep>', $aPollInfo['answers']);
$iCnt = count($aAnswers);
$aVotes = ($aPollInfo['results'] == '') ? array_fill(0, $iCnt, 0) : explode('<sep>', $aPollInfo['results']);
$aVotes[$iAnswer]++;
$iVotesCount = array_sum($aVotes);
$sVotes = implode('<sep>', $aVotes);
$GLOBALS['MySQL']->res("UPDATE `s183_polls` SET `results` = '{$sVotes}', `total_votes` = {$iVotesCount} WHERE `id` = {$iPollId}");
// recalculation of percents
$iVotesCnt = $aPollInfo['total_votes'] + 1;
$aPercents = array();
foreach ($aAnswers as $i => $sAnswer) {
$aPercents[$i] = round( (0 != $iVotesCnt ? (( $aVotes[$i] / $iVotesCnt ) * 100) : 0), 1);
}
setcookie('av' . $iPollId, '1', time() + 24*3600, '/'); // easy protection from duplicate votes
// return back to JS
echo json_encode($aPercents);
exit;
} else {
exit;
}
}
$sCode = '';
$iItemId = (int)$_GET['id'];
if ($iItemId) { // View item output
$aItemInfo = $GLOBALS['MySQL']->getRow("SELECT * FROM `s183_polls` WHERE `id` = '{$iItemId}'"); // get poll info
$aAnswers = explode('<sep>', $aItemInfo['answers']);
$iCnt = count($aAnswers);
$aVotes = ($aItemInfo['results'] == '') ? array_fill(0, $iCnt, 0) : explode('<sep>', $aItemInfo['results']);
$iVotesCnt = $aItemInfo['total_votes'];
$sAnswers = '';
foreach ($aAnswers as $i => $sAnswer) {
$fPercent = round((0 != $iVotesCnt ? (($aVotes[$i] / $iVotesCnt) * 100) : 0), 1);
$sAnswers .= "<div id='{$i}'><div>{$sAnswer} (<span>{$aVotes[$i]}</span>)</div><div class='row' style='width:{$fPercent}%'>{$fPercent}%</div></div>";
}
ob_start();
?>
<h1><?= $aItemInfo['title'] ?></h1>
<h3><?= date('F j, Y', $aItemInfo['when']) ?></h3><hr />
<div class="answers"><?= $sAnswers ?></div>
<hr /><h3><a href="<?= $_SERVER['PHP_SELF'] ?>">back</a></h3>
<script>
$(function(){
$('.answers > div').click(function () {
var answer = $(this).attr('id');
var $span = $(this).find('span');
$.post('<?= $_SERVER['PHP_SELF'] ?>', {id: <?= $iItemId ?>, answer: answer, do: 'vote'},
function(data){
if (data) {
var da = eval('(' + data + ')');
for (var p in da) {
$($('.answers > div .row')[p]).animate({
width: da[p] + "%"
}, 500);
$($('.answers > div .row')[p]).text(da[p] + "%");
}
$span.text(parseInt($span.text()) + 1);
}
}
);
});
});
</script>
<?
$sCode .= ob_get_clean();
} else {
$sCode .= '<h1>List of polls:</h1>';
// taking info about all polls from database
$aItems = $GLOBALS['MySQL']->getAll("SELECT * FROM `s183_polls` ORDER by `when` ASC");
foreach ($aItems as $i => $aItemInfo) {
$sCode .= '<h2><a href="'.$_SERVER['PHP_SELF'].'?id='.$aItemInfo['id'].'">'.$aItemInfo['title'].'</a></h2>';
}
}
?>
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<title>Creating own ajax poll system | Script Tutorials</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery-1.5.2.min.js"></script>
</head>
<body>
<div class="container">
<?= $sCode ?>
</div>
<footer>
<h2>Creating own own ajax poll system</h2>
<a href="http://www.script-tutorials.com/creating-own-ajax-poll-system/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</footer>
</body>
</html>
Когда мы откроем эту страницу в первый раз — она будет составлять список опросов. У каждого блока опроса есть своя страница. На этой странице мы собираемся отобразить заголовок опроса, дату добавления и все возможные ответы. При нажатии — скрипт отправит (POST) данные в тот же скрипт. В этот момент мы добавляем этот голос, а затем отправим обратно новые проценты для всех вариантов. И jQuery оживит все эти бары. Я добавил свои комментарии в большинстве мест для лучшего понимания.
У меня есть еще один файл PHP в моем проекте:
классы / CMySQL.php
Это сервисный класс для работы с подготовленной мной базой данных. Это хороший класс, который вы тоже можете использовать. Детали соединения с базой данных присутствуют в этом файле класса в нескольких переменных, убедитесь, что вы сможете настроить это для своей базы данных Я не буду публиковать источники этого файла — это сейчас не нужно. Доступно в упаковке.
Шаг 3. JS
JS / JQuery-1.5.2.min.js
Это просто библиотека jQuery. Доступно в упаковке.
Шаг 4. CSS
Теперь — все используемые стили CSS:
CSS / main.css
*{
margin:0;
padding:0;
}
body {
background-repeat:no-repeat;
background-color:#bababa;
background-image: -webkit-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
background-image: -moz-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
background-image: -o-radial-gradient(600px 200px, circle, #eee, #bababa 40%);
background-image: radial-gradient(600px 200px, circle, #eee, #bababa 40%);
color:#fff;
font:14px/1.3 Arial,sans-serif;
min-height:600px;
}
footer {
background-color:#212121;
bottom:0;
box-shadow: 0 -1px 2px #111111;
display:block;
height:70px;
left:0;
position:fixed;
width:100%;
z-index:100;
}
footer h2{
font-size:22px;
font-weight:normal;
left:50%;
margin-left:-400px;
padding:22px 0;
position:absolute;
width:540px;
}
footer a.stuts,a.stuts:visited{
border:none;
text-decoration:none;
color:#fcfcfc;
font-size:14px;
left:50%;
line-height:31px;
margin:23px 0 0 110px;
position:absolute;
top:0;
}
footer .stuts span {
font-size:22px;
font-weight:bold;
margin-left:5px;
}
.container {
border:3px #111 solid;
color:#000;
margin:20px auto;
padding:15px;
position:relative;
text-align:center;
width:500px;
border-radius:15px;
-moz-border-radius:15px;
-webkit-border-radius:15px;
}
.answers > div {
cursor:pointer;
margin:0 0 0 40px;
padding:10px;
text-align:left;
}
.answers > div:hover {
background-color: rgba(255, 255, 255, 0.4);
}
.answers div .row {
background-color:#0f0;
}
Live Demo
скачать в архиве
Вывод
Сегодня мы подготовили отличную систему AJAX Poll для вашего сайта. Уверен, что этот материал будет полезен для ваших собственных проектов. Удачи в работе!
Источник: http://www.script-tutorials.com/creating-own-ajax-poll-system/