
Когда вы комбинируете некоторую функциональную особенность php c jQuery. В результате у вас может получиться интересный результат. В этом обучающим руководстве мы создадим голосование, используя PHP и XHTML. Используем некоторые jQuery Ajax эффекты для того чтобы страница не перезагружалась и для добавления к голосованию немного анимации.
HTML
Давайте получим наш <head>. Установим:
<
<
<
– style.css управляет CSS разметкой.
– jquery.js главная jQuery библиотека
– jquery.cookie.js Плагин (автор – Klaus Hartl)добавляет управление куки в jQuery.
–poll.js это Javascript который делает голосование динамическим
Дальше мы создаем простую форму голосования:

<
<
<
<
<
<
<
<
<
<
</
</
Пока, что эта форма будет обрабатыватся с помощью PHP, и когда мы запустим Javascript с помощью jQuery. PHP и Javascript предназначены для вытягивания информации ID вариантов для выбора с тега – value. это HTML элемент пробел и → это стрелка.
PHP
Введение
Если javascript отключен, тогда php:
1. Получает GET/POST запрос с формы.
2. Устанавливает и проверяет куки.
3. Скрипт может знать, что запрос с уникального IP.
4. Сохранять голос в плоском файле DB.
5. Возвращать результат, включенный в HTML файл.
Если javascript включен, тогда php:
1. Получает GET/POST запрос с формы.
2. Скрипт может знать, что запрос с уникального IP.
3. Сохранять голос в плоском файле DB.
4. Получать результат как JSON.
Для плоских файлов DB мы будем использовать PHP Flatfile package (автор Luke Plant). Ниже в тексте буду просто называть flatfile или база данных.
Сначала нам нужен массив с именами и ID опций голосования.
$options[1] = 'jQuery';
$options[2] = 'Ext JS';
$options[3] = 'Dojo';
$options[4] = 'Prototype';
$options[5] = 'YUI';
$options[6] = 'mootools';
flatfile использует цифры для идентификации колонок. Давайте установить константы для конвертирования их в имена.
Когда форма отправлена, php должен знать в какой файл нужно вставить результат. Поэтому мы устанавливаем еще одну константу:
Мы должны подключить flatfile.php и инициализировать объект базы данных:
$db = new Flatfile();
Плоские файлы это текстовые файлы, которые хранятся в директории data.
Если мы получаем запрос с poll параметром, тогда это статическая форма, и мы обрабатываем ее. Если запрос имеет vote параметр, тогда это Ajax запрос. В любом другом случае мы просто возвращаем HTML_FILE.
poll_submit();
}
else if ($_GET['vote'] || $_POST['vote']) {
poll_ajax();
}
else {
poll_default();
}
poll_default()
global $db;
$ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);
if (!
}
else {
poll_return_results($_COOKIE['vote_id']);
}
}
poll_default() обрабатывает напрямую запрос в скрипте без GET/POST запроса. Global делает $db объект видимым в области видимости функции.
Скрипт проверяет ваш IP на уникальность для уверенности, что вы один раз проголосовали.
Если нет куки и в запросе IP пустое, значит, клиент еще не голосовал, поэтому мы посылаем Html файл который содержит форму. В другом случае мы отсылаем результат.
}
else {
poll_return_results($_COOKIE['vote_id']);
}
poll_submit()
global $db;
global $options;
$id = $_GET['poll'] || $_POST['poll'];
$id =
$ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);
if (!
$row = $db->selectUnique(VOTE_DB, OPT_ID, $id);
if (!
$ip[0] = $_SERVER['REMOTE_ADDR'];
$db->insert(IP_DB, $ip);
$new_votes = $row[OPT_VOTES]+1;
$db->updateSetWhere(VOTE_DB,
poll_return_results($id);
}
else if ($options[$id]) {
$ip[0] = $_SERVER['REMOTE_ADDR'];
$db->insert(IP_DB, $ip);
$new_row[OPT_ID] = $id;
$new_row[OPT_TITLE] = $options[$id];
$new_row[OPT_VOTES] = 1;
$db->insert(VOTE_DB, $new_row);
poll_return_results($id);
}
}
else {
poll_return_results($id);
}
}
poll_submit() берет данные отправленной формы. Проверяет, проголосовал ли текущий клиент и затем абгрейдит базу данных, добавляя голос.
Эти строчки получают выбранные пользователем ID опций, и устанавливают к ним переменную $id
$id =
Нам нужно проверить, если ли такие опции еще в базе данных.
Если они есть в базе, тогда мы должны запустить функцию updateSetWhere(), а иначе вставляем в базу новую запись функцией insert():
$new_votes = $row[OPT_VOTES]+1;
$db->updateSetWhere(VOTE_DB,
poll_return_results($id);
}
else if ($options[$id]) {
$new_row[OPT_ID] = $id;
$new_row[OPT_TITLE] = $options[$id];
$new_row[OPT_VOTES] = 1;
$db->insert(VOTE_DB, $new_row);
poll_return_results($id);
}
В любом случае нам нужно вставить IP в базу и установить куки на один год.
$db->insert(IP_DB, $ip);
poll_return_results()
global $db;
$html =
$results_html = "<div id='poll-container'><div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n";
$rows = $db->selectWhere(VOTE_DB,
new SimpleWhereClause(OPT_ID, "!=", 0), -1,
new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));
foreach ($rows as $row) {
$total_votes = $row[OPT_VOTES]+$total_votes;
}
foreach ($rows as $row) {
$percent =
if (!$row[OPT_ID] == $id) {
$results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='bar-container'><div id='bar". $row[OPT_ID] ."'style='width:$percent%;'> </div><strong>$percent%</strong></dd>\n";
}
else {
$results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='bar-container'><div id='bar". $row[OPT_ID] ."' style='width:$percent%;background-color:#0066cc;'> </div><strong>$percent%</strong></dd>\n";
}
}
$results_html .= "</dl><p>Total Votes: ". $total_votes ."</p></div></div>\n";
$results_regex = '/<div id="poll-container">(.*?)<\/div>/s';
$return_html =
print $return_html;
}
poll_return_results() генерирует результат голосования, берез HTML файл и заменяет форму результатом. Затем возвращает файл клиенту.
Сначала давайте получим содержимое HTML файла и назначим ему переменную $html:
Дальше мы получим начало html cтруктуры:
Чтобы создать HTML результат нам нужно получить все опции с базы данных отсортированные по номеру голосования.
new SimpleWhereClause(OPT_ID, "!=", 0), -1,
new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));
Нам также нужно общее количество голосов для подсчета процентов.
$total_votes = $row[OPT_VOTES]+$total_votes;
}
Дальше вычисляем проценты голосов текущей опции:
$percent =
HTML результат будет списком (<dl>) стилизированный с помощью CSS для создания графика.
Также нужно проверить является текущая опция той за которую клиент проголосовал, и изменить цвет в ней.
}
else {
$results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='bar-container'><div id='bar". $row[OPT_ID] ."' style='width:$percent%;background-color:#0066cc;'> </div><strong>$percent%</strong></dd>\n";
}
Дальше мы добавляем общее количество голосов и закрываем html тег:
Это регулярное выражение, которое находит poll-container <div>:
Последним шагом в этой функции заменяем форму голосования, на результат, используя регулярные выражения, и возвращаем результат:
print $return_html;
poll_ajax()
global $db;
global $options;
$id = $_GET['vote'] || $_POST['vote'];
$ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);
if (
$ip[0] = $_SERVER['REMOTE_ADDR'];
$db->insert(IP_DB, $ip);
if ($id != 'none') {
$row = $db->selectUnique(VOTE_DB, OPT_ID, $id);
if (!
$new_votes = $row[OPT_VOTES]+1;
$db->updateSetWhere(VOTE_DB,
}
else if ($options[$id]) {
$new_row[OPT_ID] = $id;
$new_row[OPT_TITLE] = $options[$id];
$new_row[OPT_VOTES] = 1;
$db->insert(VOTE_DB, $new_row);
}
}
}
$rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), -1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));
}
poll_ajax() берет запрос от Javascript, добавляет голос в базу, и возвращает результат в JSON формате.
В этой функции несколько строчек кода, которые отличаются от фунции poll_submit(). Первый определяет – нужен ли йаваскрипту результат, и голоса не подсчитываются:
Несколько других строчек выбирают все данные с базы, и возвращают их в JSON формате:
CSS
width: 250px;
position: relative;
rightright: 30px;
}
.bar-title {
position: relative;
float: left;
width: 104px;
line-height: 20px;
margin-right: 17px;
font-weight: bold;
text-align: rightright;
}
.bar-container {
position: relative;
float: left;
width: 110px;
height: 10px;
margin: 0px 0px 15px;
}
.bar-container div {
background-color:#cc4400;
height: 20px;
}
.bar-container strong {
position: absolute;
rightright: -32px;
top: 0px;
overflow: hidden;
}
#poll-results p {
text-align: center;
}
CSS стили возвращают PHP или Javascript.
– .graph стилизированный контейнер для прямоугольников, заголовков и процентов. Ширина может быть разная для сайтов.
– .bar-title стилизированный заголовок для прямоугольника графика.
– .bar-container стилизированный прямоугольник и контейнер процентов.
– .bar-container strong стили процентов.
– #poll-results p стиль результатов голосования.
Javascript
ВВЕДЕНИЕ
Javascript будет перехватывать кнопку отправки формы, посылая голос с помощь Ajax, и в будет добавлять анимацию.
Сначало некоторые глобальные переменные. Первые 3 вы можете узнать по скрипту PHP. votedID хранит ID, который пользователь выбрал при голосовании.
var OPT_TITLE = 1;
var OPT_VOTES = 2;
var votedID;
Дальше нам нужна jQuery ready функция, которая запускается, когда страница загружается.
Внутри этой функции мы регистрируем обработчик для кнопки голосования, которая будет запускать функцию formProcess, когда нажата кнопка для получения результата.
Также нужно проверить существование тэга div, и если существует добавить анимации в результат.
animateResults();
}
Если у нас есть куки, мы напрямую загружаем результат, так как пользователь уже проголосовал. Для этого мы берем id c куки, получаем результат с PHP, и вставляем в функцию loadResults().
$("#poll-container").empty();
votedID = $.cookie('vote_id');
$.getJSON("poll.php?vote=none",loadResults);
}
formProcess()
event.preventDefault();
var id = $("input[@name='poll']:checked").attr("value");
id = id.replace("opt",'');
$("#poll-container").fadeOut("slow",function(){
$(this).empty();
votedID = id;
$.getJSON("poll.php?vote="+id,loadResults);
$.cookie('vote_id', id, {expires: 365});
});
}
formProcess() вызывается событием “submit”. Благодаря этому форма нормально не отправляется. Вместо этого проверяет или устанавливает куки и отправляет данные с помощью Ajax. Когда вызывается функция loadResults() которая конвертирует результат в HTML.
Сначала мы предотвращаем действие по умолчанию(отправка формы).
Дальше мы получаем текущий выбранный ID опции:
id = id.replace("opt",'');
input[@name='poll']:checked это jQuery селектор который выбирает input с атрибутом name=’poll’ который выбран. attr(”value”) получаем значение объекта, который в нашем случае является optn, где n является ID опции.
Теперь мы имеем ID, и можем его обрабатывать. Для начала делаем так чтобы форма исчезла. И запускаем анонимную функцию как обратный вызов, который запустится когда форма исчезнит.
После затухании формы мы удаляем форму с DOM используя функцию empty():
С помощью функции $.getJSON()которой получает GET результат для JSON объекта. Когда мы имеем объект – получаем результат в функции loadResults():
Последнее, что нужно сделать, это установить куки:
$.cookie('vote_id', id, {expires: 365});
loadResults()
var total_votes = 0;
var percent;
for (id in data) {
total_votes = total_votes+parseInt(data[id][OPT_VOTES]);
}
var results_html = "<div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n";
for (id in data) {
percent = Math.round((parseInt(data[id][OPT_VOTES])/parseInt(total_votes))*100);
if (data[id][OPT_ID] !== votedID) {
results_html = results_html+"<dt class='bar-title'>"+data[id][OPT_TITLE]+"</dt><dd class='bar-container'><div id='bar"+data[id][OPT_ID]+"'style='width:0%;'> </div><strong>"+percent+"%</strong></dd>\n";
} else {
results_html = results_html+"<dt class='bar-title'>"+data[id][OPT_TITLE]+"</dt><dd class='bar-container'><div id='bar"+data[id][OPT_ID]+"'style='width:0%;background-color:#0066cc;'> </div><strong>"+percent+"%</strong></dd>\n";
}
}
results_html = results_html+"</dl><p>Total Votes: "+total_votes+"</p></div>\n";
$("#poll-container").append(results_html).fadeIn("slow",function(){
animateResults();});
}
loadResults() вызывается через $.getJSON() и вставляет JSON который содержит результат с базы данных. Эта функция очень похожа на функцию php – poll_return_results() но с некоторыми отличиями. Первое отличие в том, что мы устанавливаем ширину нашего прямоугольника в 0%, так как мы будем анимировать его. Другое отличие в том, что мы используем функцию append() вместо регулярного выражения для вывода результата. После того как результат появился функция вызывает animateResults().
animateResults()
$("#poll-results div").each(function(){
var percentage = $(this).next().text();
$(this).css({width: "0%"}).animate({
width: percentage}, 'slow');
});
}
animateResults() проходит циклом через каждый прямоугольник и анимирует по ширине основываясь на процентах.
each() это jQuery функция которая проходит массивом через каждый выбранный элемент:
Когда мы уверенны, что ширина установленна в 0%, тогда анимируем ее:
width: percentage}, 'slow');
Это вольный перевод статьи -ОРИГИНАЛ
Пример работы можно скачать тут – ИСХОДНИКИ








Nadia on Сентябрь 24th, 2010
Клёвая статья… только мне как новичку слишком много информации… надеюсь разобраться!