Программирование, СМС, Webasyst, Drupal, PHP, личная эффективность

 
 

Создаем динамическое голосование используя jQuery и PHP

Август 9, 2010   |   Категории: jQuery, php, Новости, веб мастерим

голосование используя php и jquery
Когда вы комбинируете некоторую функциональную особенность php c jQuery. В результате у вас может получиться интересный результат. В этом обучающим руководстве мы создадим голосование, используя PHP и XHTML. Используем некоторые jQuery Ajax эффекты для того чтобы страница не перезагружалась и для добавления к голосованию немного анимации.

HTML

Давайте получим наш <head>. Установим:

    <link href="style.css" rel="stylesheet" type="text/css" />  
    <script src="jquery.js" type="text/javascript" charset="utf-8"></script>  
    <script src="jquery.cookie.js" type="text/javascript" charset="utf-8"></script>  
    <script src="poll.js" type="text/javascript" charset="utf-8"></script>

– style.css управляет CSS разметкой.
– jquery.js главная jQuery библиотека
– jquery.cookie.js Плагин (автор – Klaus Hartl)добавляет управление куки в jQuery.
–poll.js это Javascript который делает голосование динамическим

Дальше мы создаем простую форму голосования:

голосование используя php и jquery

    <div id="poll-container">  
        <h3>Poll</h3>  
        <form id='poll' action="poll.php" method="post" accept-charset="utf-8">  
            <p>Pick your favorite Javascript framework:</p>  
            <p><input type="radio" name="poll" value="opt1" id="opt1" /><label for='opt1'>&nbsp;jQuery</label>  
            <input type="radio" name="poll" value="opt2" id="opt2" /><label for='opt2'>&nbsp;Ext JS</label>  
            <input type="radio" name="poll" value="opt3" id="opt3" /><label for='opt3'>&nbsp;Dojo</label>
            <input type="radio" name="poll" value="opt4" id="opt4" /><label for='opt4'>&nbsp;Prototype</label>
            <input type="radio" name="poll" value="opt5" id="opt5" /><label for='opt5'>&nbsp;YUI</label>
            <input type="radio" name="poll" value="opt6" id="opt6" /><label for='opt6'>&nbsp;mootools</label>
            <input type="submit" value="Vote &rarr;" /></p>  
        </form>  
    </div>

Пока, что эта форма будет обрабатыватся с помощью 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 опций голосования.

 <?php  
  $options[1] = 'jQuery';  
  $options[2] = 'Ext JS';  
  $options[3] = 'Dojo';  
  $options[4] = 'Prototype';  
  $options[5] = 'YUI';  
  $options[6] = 'mootools';

flatfile использует цифры для идентификации колонок. Давайте установить константы для конвертирования их в имена.

    define('OPT_ID', 0);  
    define('OPT_TITLE', 1);  
    define('OPT_VOTES', 2);

Когда форма отправлена, php должен знать в какой файл нужно вставить результат. Поэтому мы устанавливаем еще одну константу:

define('HTML_FILE', 'index.html');

Мы должны подключить flatfile.php и инициализировать объект базы данных:

  require_once('flatfile.php');  
  $db = new Flatfile();

Плоские файлы это текстовые файлы, которые хранятся в директории data.

  $db->datadir = 'data/';  
  define('VOTE_DB', 'votes.txt');  
  define('IP_DB', 'ips.txt');

Если мы получаем запрос с poll параметром, тогда это статическая форма, и мы обрабатываем ее. Если запрос имеет vote параметр, тогда это Ajax запрос. В любом другом случае мы просто возвращаем HTML_FILE.

    if ($_GET['poll'] || $_POST['poll']) {  
      poll_submit();  
    }  
    else if ($_GET['vote'] || $_POST['vote']) {  
      poll_ajax();  
    }  
    else {  
      poll_default();  
    }

poll_default()

    function poll_default() {  
      global $db;  
     
      $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);  
     
      if (!isset($_COOKIE['vote_id']) && empty($ip_result)) {  
        print file_get_contents(HTML_FILE);  
      }  
      else {  
        poll_return_results($_COOKIE['vote_id']);  
      }  
    }

poll_default() обрабатывает напрямую запрос в скрипте без GET/POST запроса. Global делает $db объект видимым в области видимости функции.
Скрипт проверяет ваш IP на уникальность для уверенности, что вы один раз проголосовали.

$ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);

Если нет куки и в запросе IP пустое, значит, клиент еще не голосовал, поэтому мы посылаем Html файл который содержит форму. В другом случае мы отсылаем результат.

  if (!isset($_COOKIE['vote_id']) && empty($ip_result)) {  
    print file_get_contents(HTML_FILE);  
  }  
  else {  
    poll_return_results($_COOKIE['vote_id']);  
  }

poll_submit()

    function poll_submit() {  
      global $db;  
      global $options;  
     
      $id = $_GET['poll'] || $_POST['poll'];  
      $id = str_replace("opt", '', $id);  
     
      $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);  
     
      if (!isset($_COOKIE['vote_id']) && empty($ip_result)) {  
        $row = $db->selectUnique(VOTE_DB, OPT_ID, $id);  
        if (!empty($row)) {  
          $ip[0] = $_SERVER['REMOTE_ADDR'];  
          $db->insert(IP_DB, $ip);  
     
          setcookie("vote_id", $id, time()+31556926);  
     
          $new_votes = $row[OPT_VOTES]+1;  
          $db->updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $id));  
     
          poll_return_results($id);  
        }  
        else if ($options[$id]) {  
          $ip[0] = $_SERVER['REMOTE_ADDR'];  
          $db->insert(IP_DB, $ip);  
     
          setcookie("vote_id", $id, time()+31556926);  
     
          $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 = $_GET['poll'] || $_POST['poll'];  
  $id = str_replace("opt", '', $id);

Нам нужно проверить, если ли такие опции еще в базе данных.

$row = $db->selectUnique(VOTE_DB, OPT_ID, $id);

Если они есть в базе, тогда мы должны запустить функцию updateSetWhere(), а иначе вставляем в базу новую запись функцией insert():

    if (!empty($row)) {  
      $new_votes = $row[OPT_VOTES]+1;  
      $db->updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $id));  
     
      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 в базу и установить куки на один год.

  $ip[0] = $_SERVER['REMOTE_ADDR'];  
  $db->insert(IP_DB, $ip);    
  setcookie("vote_id", $id, time()+31556926);

poll_return_results()

    function poll_return_results($id = NULL) {  
        global $db;  
     
        $html = file_get_contents(HTML_FILE);  
        $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 = round(($row[OPT_VOTES]/$total_votes)*100);  
          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%;'>&nbsp;</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;'>&nbsp;</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 = preg_replace($results_regex, $results_html, $html);  
        print $return_html;  
    }

poll_return_results() генерирует результат голосования, берез HTML файл и заменяет форму результатом. Затем возвращает файл клиенту.

Сначала давайте получим содержимое HTML файла и назначим ему переменную $html:

$html = file_get_contents(HTML_FILE);

Дальше мы получим начало html cтруктуры:

$results_html = "<div id='poll-container'><div id='poll-results'><h3>Poll Results</h3>\n<dl class='graph'>\n";

Чтобы создать HTML результат нам нужно получить все опции с базы данных отсортированные по номеру голосования.

  $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 = round(($row[OPT_VOTES]/$total_votes)*100);

HTML результат будет списком (<dl>) стилизированный с помощью CSS для создания графика.

$results_html .= "<dt class='bar-title'>". $row[OPT_TITLE] ."</dt><dd class='bar-container'><div id='bar". $row[OPT_ID] ."'style='width:$percent%;'>&nbsp;</div><strong>$percent%</strong></dd>\n";

Также нужно проверить является текущая опция той за которую клиент проголосовал, и изменить цвет в ней.

  if (!$row[OPT_ID] == $id) {  
  }  
  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;'>&nbsp;</div><strong>$percent%</strong></dd>\n";  
  }

Дальше мы добавляем общее количество голосов и закрываем html тег:

$results_html .= "</dl><p>Total Votes: ". $total_votes ."</p></div></div>\n";

Это регулярное выражение, которое находит poll-container <div>:

$results_regex = '/<div id="poll-container">(.*?)<\/div>/s';

Последним шагом в этой функции заменяем форму голосования, на результат, используя регулярные выражения, и возвращаем результат:

  $return_html = preg_replace($results_regex, $results_html, $html);  
  print $return_html;

poll_ajax()

    function poll_ajax() {  
      global $db;  
      global $options;  
     
      $id = $_GET['vote'] || $_POST['vote'];  
     
      $ip_result = $db->selectUnique(IP_DB, 0, $_SERVER['REMOTE_ADDR']);  
     
      if (empty($ip_result)) {  
        $ip[0] = $_SERVER['REMOTE_ADDR'];  
        $db->insert(IP_DB, $ip);  
     
        if ($id != 'none') {  
          $row = $db->selectUnique(VOTE_DB, OPT_ID, $id);  
          if (!empty($row)) {  
            $new_votes = $row[OPT_VOTES]+1;  
     
            $db->updateSetWhere(VOTE_DB, array(OPT_VOTES => $new_votes), new SimpleWhereClause(OPT_ID, '=', $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);  
          }  
        }  
      }  
     
      $rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), -1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));  
      print json_encode($rows);  
    }

poll_ajax() берет запрос от Javascript, добавляет голос в базу, и возвращает результат в JSON формате.
В этой функции несколько строчек кода, которые отличаются от фунции poll_submit(). Первый определяет – нужен ли йаваскрипту результат, и голоса не подсчитываются:

if ($id != 'none')

Несколько других строчек выбирают все данные с базы, и возвращают их в JSON формате:

    $rows = $db->selectWhere(VOTE_DB, new SimpleWhereClause(OPT_ID, "!=", 0), -1, new OrderBy(OPT_VOTES, DESCENDING, INTEGER_COMPARISON));  
    print json_encode($rows);

CSS

    .graph {  
      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_ID = 0;  
  var OPT_TITLE = 1;  
  var OPT_VOTES = 2;  
  var votedID;

Дальше нам нужна jQuery ready функция, которая запускается, когда страница загружается.

$(document).ready(function(){

Внутри этой функции мы регистрируем обработчик для кнопки голосования, которая будет запускать функцию formProcess, когда нажата кнопка для получения результата.

$("#poll").submit(formProcess);

Также нужно проверить существование тэга div, и если существует добавить анимации в результат.

  if ($("#poll-results").length > 0 ) {  
      animateResults();  
  }

Если у нас есть куки, мы напрямую загружаем результат, так как пользователь уже проголосовал. Для этого мы берем id c куки, получаем результат с PHP, и вставляем в функцию loadResults().

    if ($.cookie('vote_id'))  
        $("#poll-container").empty();  
        votedID = $.cookie('vote_id');  
        $.getJSON("poll.php?vote=none",loadResults);  
    }

formProcess()

    function formProcess(event){  
      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.

Сначала мы предотвращаем действие по умолчанию(отправка формы).

event.preventDefault();

Дальше мы получаем текущий выбранный ID опции:

    var id = $("input[@name='poll']:checked").attr("value");  
    id = id.replace("opt",'');

input[@name='poll']:checked это jQuery селектор который выбирает input с атрибутом name=’poll’ который выбран. attr(”value”) получаем значение объекта, который в нашем случае является optn, где n является ID опции.
Теперь мы имеем ID, и можем его обрабатывать. Для начала делаем так чтобы форма исчезла. И запускаем анонимную функцию как обратный вызов, который запустится когда форма исчезнит.

$("#poll-container").fadeOut("slow",function(){

После затухании формы мы удаляем форму с DOM используя функцию empty():

$(this).empty();

С помощью функции $.getJSON()которой получает GET результат для JSON объекта. Когда мы имеем объект – получаем результат в функции loadResults():

$.getJSON("poll.php?vote="+id,loadResults);
Последнее, что нужно сделать, это установить куки:
$.cookie('vote_id', id, {expires: 365});

loadResults()

    function loadResults(data) {  
      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%;'>&nbsp;</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;'>&nbsp;</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()

  function animateResults(){  
    $("#poll-results div").each(function(){  
        var percentage = $(this).next().text();  
        $(this).css({width: "0%"}).animate({  
                 width: percentage}, 'slow');  
    });  
  }

animateResults() проходит циклом через каждый прямоугольник и анимирует по ширине основываясь на процентах.
each() это jQuery функция которая проходит массивом через каждый выбранный элемент:

    $("#poll-results div").each(function(){

Когда мы уверенны, что ширина установленна в 0%, тогда анимируем ее:

  $(this).css({width: "0%"}).animate({  
    width: percentage}, 'slow');

Это вольный перевод статьи -ОРИГИНАЛ
Пример работы можно скачать тут – ИСХОДНИКИ



 
 

3 Комментариев

Nadia  on Сентябрь 24th, 2010

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

Leka  on Октябрь 21st, 2010

А где ссылка на работающий пример?

Valik  on Октябрь 24th, 2010

Можно скачать тут – http://vlb.org.ua/scripts_d/demo.zip

Оставить комментарий




 

 
 

На сайте freesoftspace.com можно найти много полезных бесплатных программ для веб разработки

 
 


38201110912430120x600.gif
Каталог блогов
2009-2012   При копировании материала активная ссылка на web-grand.ru обязательна