Уважаемые читатели сайта Ajaxs.ru

Очень рад что вы зашли на мой сайт. Надеюсь, Вы сможете найти здесь для себя полезную информацию. Зарегистрировавшись на сайте вы получаете ряд преимуществ:
1. При комментировании Вам не нужно вводить имя и капчу с картинки
2. Вы можете получать уведомления на Email к интерисующим вас урокам
3. Вы можете редактировать свои комментарии

Вход на сайт


Забыли пароль



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


Войти на сайт

Зарегистрироваться

Главная / Уроки по AJAX / Просмотр урока

     

Создание сайтов


Вам нужен небольшой сайт или просто хотите доработать уже существующий? | Подробнее

Делаем скрипт голосования с нуля

Лучший способ узнать ответ на вопрос у читателей Вашего сайта это произвести опрос, предложив несколько вариантов ответа. Для таких целей существует большое количество готовых скриптов с различным функционалом, все они имеют свои преимущества и недостатки.  Целью этого урока будет научиться создавать собственный скрипт голосования, пусть и довольно простой, но вполне работоспособный. Чтобы избежать повторных голосов мы сделаем блокировку пользователей по ip и cookie. Все действия, конечно же, будут происходить без перезагрузки страницы, а так же сделаем небольшую, но эффектную анимацию для отображения результатов.

Подключаем jQuery на страницу:

<script type="text/javascript" src="jquery-1.5.1.min.js"></script>

Теперь создадим каркас для нашего голосования:

<div id="pollAjaxs">
  <p
class="pollTitle"></p>
  <div
id="poll">
    <form
method="get" id="formPoll">
      <div
class="button">
         <a
href="#" id="vote">Голосовать</a>
      </div>
    </form>
  </div>
  <div
id="resaltPoll">
    <div
class="button" id="er"></div>
  </div>
</div>

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

CREATE TABLE IF NOT EXISTS `answer` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `answer` varchar(100) NOT NULL,
  `result` int(5) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=9 ;

И таблицу в которой будут храниться ip проголосовавших

CREATE TABLE IF NOT EXISTS `ip` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `ip` varchar(15) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=2 ;

Теперь осуществим вывод этих вариантов из базы на экран. Забегая немного вперед, пропишем еще и условия для вывода проголосовавших и не проголосовавших. Вот что у нас должно получиться:

<div id="pollAjaxs">
  <p
class="pollTitle">Вопрос?</p>
     <?php if(empty($_COOKIE['opros']) || ($_COOKIE['opros']) == '' || empty($ip['id'])){ ?>
     <div id="poll">
       <form
method="get" id="formPoll">
       <?php
       mysql_data_seek($result, 0);
       $answer = mysql_fetch_array($result);
       $i = 0;
       do{
         echo "<div class='answer'>
         <input type='radio' name='otvet' value='"
.$answer['id']."' class='otvet' id='".$i."'> ".$answer['answer'].
         "</div>\r\n";
         $i++;
       }while($answer = mysql_fetch_array ($result));
       ?>
       <div class="button">
          <a
href="#" id="vote">Голосовать</a>
       </div>
       </form>
     </div>

     <?php } ?>
     <div id="resaltPoll">
        <?php
        mysql_data_seek($result, 0);
        $answer = mysql_fetch_array($result);
        $i = 0;
        do{
           echo "<div class='answer' id='res_".$i."'>
           <div class='nameanswer'></div>
           <div class='font'></div>
           </div>\r\n"
;
           $i++;
        }while($answer = mysql_fetch_array ($result));
        ?>
        <div class='button' id='er'></div>
     </div>
</div>

Само же подключение к базе у нас будет чуть выше, до него еще доберемся. Теперь  добавим стилей, чтобы придать всему этому божеский вид:

* { margin: 0; padding: 0; }
a:link, a:visited {
color: #004F8B;
text-decoration: none;
}
a:hover {
text-decoration: none;
}
#pollAjaxs{
font: 11px Tahoma, Arial, Helvetica, sans-serif;
width:200px;
min-height:190px;
border:1px solid #666;
margin:10px;
padding:8px;
}
.pollTitle{
text-align:center;
margin-bottom:15px;
font-weight:700;
}
#resaltPoll{
display:none;
}
.button{
text-align:center;
}
.button a{
background-color:#B4D2F9;
border:1px solid #666;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
width:60px;
margin:8px auto;
padding:4px;
}
#resaltshow, #pollshow{
border:1px solid #666;
padding:4px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
}
#resaltshow{
width:60px;
margin:8px auto;
}
.answer{
height:30px;
margin:5px 0;
}
.font{
height:10px;
background:#eee url('bg.png') repeat-x;
margin:3px 0;
width:0;
border-radius: 2px;
}
.pollRed{
color:#D80000;
}
.pollGreen{
color:#00A331;
}
.pollRed span, .pollGreen span{
color:#424242;
}

Изначально блок с результатами у нас будет скрыт, если пользователь еще не проголосовал или отображаться, если голос был произведен. Чуть позже мы напишем в скрипте чтобы он показывался после того как пользователь проголосовал. При нажатии на кнопку голосовать у нас отправляется ajax запрос с вариантом ответа и заносится в базу, после чего блок #poll скрывается и отображаются результаты. Но для вывода результатов нам нужно произвести некоторые расчеты с учетом нового голоса. Прежде всего, нам нужно определиться с шириной блока голосования, так как от этого будет зависеть ширина полосок при отображении результатов. Для удобства я возьму ширину равную 200 пикселям, следовательно, 1% полоски результатов будет занимать 2 пикселя.

Теперь я приведу весь скрипт,  а затем разъясню что для чего нужно:

<script type="text/javascript">
//результаты уже проголосовавших
var answer = new Array();
<?php
include("connect.php");
$result = mysql_query("SELECT * FROM answer",$db);
$answer = mysql_fetch_array($result);
$arrayips = mysql_query("SELECT * FROM ip WHERE ip = '$_SERVER[REMOTE_ADDR]'",$db);
$ip = mysql_fetch_array($arrayips);
$i = 0;
do{
  echo "answer[".$i."] = [".$answer['result'].", '".$answer['answer']."'];\r\n";
  $i++;
}while($answer = mysql_fetch_array ($result));
?>
//1% полоски результатов будет занимать 2 пикселя
var background = 2;
//Сумма всех результатов
for (var i = 0, sum = 0; i < answer.length; i++){
  sum += answer[i][0];
}
//Вычисляем процентное соотношение результатов
//и длинну полосы результатов

var percent = 100/sum;
var answerWidth = new Array();
var answerPercent = new Array();
for (var i = 0; i < answer.length; i++){
   answerPercent[i] = answer[i][0]*percent;
   answerWidth[i] = answerPercent[i]*background;
}
<?php if(empty($_COOKIE['opros']) || ($_COOKIE['opros']) == '' || empty($ip['id'])){ ?>
//Отправлям запрос обработчику по нажатию на кнопку голосовать
//и выводим результаты на экран

$(function() {
  $("#vote").click(function(){
     var idAnswer = $('.otvet:checked').val();
     $.ajax({
        url: "action.php",
        type: "GET",
        data: {"answer": idAnswer},
        cache: false,
        success: function(response){
           if(response == 1){
              var p = $(".otvet:checked").attr("id");
              if(p != undefined){
                 sum++;
                 var newPercent = 100/sum;
                 answer[p][0]++;
                 var newAnswerWidth = new Array();
                 var newAnswerPercent = new Array();
                 $("#poll").hide();
                 $("#resaltPoll").fadeIn(800);
                 for (var i = 0; i < answer.length; i++){
                    newAnswerPercent[i] = answer[i][0]*newPercent;
                    newAnswerWidth[i] = newAnswerPercent[i]*background;
                    $("#res_" + i + " .font").animate({width: newAnswerWidth[i]}, 800);
                    $("#res_" + i + " .nameanswer").html(answer[i][1] + " <strong>" + newAnswerPercent[i].toFixed(2) + "</strong> (" + answer[i][0] + ")");
                 }
                 $("#er").addClass("pollGreen").html("Спасибо, Ваш голос принят<br><span>Всего проголосовало: " + sum + "</span>");
               }
            }else{
               alert("Ошибка");
            }
          }
       });                          
       return false;
    });
});
<?php } ?>
$(document).ready(function(){
<?php if(isset($_COOKIE['opros']) || ($_COOKIE['opros']) != '' || isset($ip['id'])){ ?>
   //Эту часть мы выводим если пользователь уже проголосовал
   $("#resaltPoll").fadeIn(800);
   for (var i = 0; i < answer.length; i++){
      $("#res_" + i + " .font").animate({width: answerWidth[i]}, 800);
      $("#res_" + i + " .nameanswer").html(answer[i][1] + " <strong>" + answerPercent[i].toFixed(2) + "</strong> (" + answer[i][0] + ")");
   }
   $("#er").addClass("pollRed").html("Вы уже голосовали<br><span>Всего проголосовало: " + sum + "</span>");
<?php } ?>
});
</script>

Итак, начнем по порядку. Для начала подключимся к и получим все результаты уже имеющиеся в базе и заносим их в массив answer, они нам понадобятся для дальнейших расчетов. Переменная background равна 2 это и есть та самая ширина для отображения полоски результатов, о которой уже говорилось выше, она так же пригодится в дальнейшем. Теперь нам нужно подсчитать суму всех голосов sum. Это нам нужно для определения процентного соотношения между вариантами ответов. Далее мы вычисляем это самое процентное соотношение answerPercent и длину answerWidth каждой полоски результатов в пикселях. Затем смотрим по кукам и ip, если пользователь еще не голосовал, то выводим для него часть кода, которая будет отправлять ajax запрос на сервер и затем выводить результат с учетом нового голоса. В случае удачного ответа от сервера нам вернется 1 после чего мы производим перерасчет уже существующих результатов и выведем их на экран при этом блок с выбором вариантов скроем. Далее идет часть кода, которая выводит нам результаты для уже проголосовавших пользователей на основе предшествующих рассчетов.

Что касается обработчика, давайте его создадим. Он у нас будет принимать всего один параметр - это id варианта ответа и прибавлять к результату 1. Код довольно прост:

<?php
include("connect.php");
header("Content-type: text/html; charset=windows-1251");
if($_GET['answer']){
   $answer = $_GET['answer'];
   $answer = addslashes($answer);
   $answer = htmlspecialchars($answer);
   $answer = stripslashes($answer);
   $answer = mysql_real_escape_string($answer);
               
   $arrayips = mysql_query("SELECT * FROM ip WHERE ip = '$_SERVER[REMOTE_ADDR]'",$db);
   $ip = mysql_fetch_array($arrayips);
   if(empty($_COOKIE['opros']) || ($_COOKIE['opros']) == '' || empty($ip['id'])){
      $result = mysql_query("UPDATE answer SET result = result+1 WHERE id='$answer'",$db);
      if($result == true){
          setcookie("opros", $answer, time()+9999999);
          mysql_query("INSERT INTO ip (ip) VALUES ('$_SERVER[REMOTE_ADDR]')",$db);
          echo 1; //Изменения сохранены                                        
      }else{
          echo 0; //не сохранены
      }
   }else{
      echo 0; //не сохранены
   }
}
?>

После всех этих манипуляций обработчик вернет нам 1 в случае если все прошло успешно или 0 если возникли проблемы.

Вот пожалуй и все что я хотел рассказать, несмотря на немного громоздкий код все довольно просто.

Автор: Евгений Бочкарев Урок добавлен: 25 Августа 2012 в 00:15 Просмотров: 34474

Условия копирования материалов сайта

Все комментарии

Посмотреть предыдущие комментарии (28)

#29 ZICK 01-02-2015 в 15:08
кто нибудь делал подключение опроса к новостям сайта, чтобы на странице было более чем 2 голосования?
#30 Юрец 30-08-2015 в 21:23
Здравствуйте народ, очень понравился этот Опрос, но никак не могу его установить на сайт, выдаёт ошибку "Warning: mysql_data_seek(): supplied argument is not a valid MySQL result resource in /home/onlyfive/public_html/index_2.php on line 107" , с Базами Данных MySQL я на Вы и походу там и косяк, БД создал, добавил для неё пользователя и установил для него все права, также создал в БД две таблицы "answer и ip", они отображаются в списке базы, но что- то всё равно ничего не выходит, подскажите пожалуйста в чём может быть дело.
#31 Юрий 31-08-2015 в 21:34
Скажите пожалуйста, а как назвать подключаемую БД, или это не имеет значения?
#32 Meedik 12-11-2015 в 18:42
Установил , все работает отлично, но есть одна проблема.
Если чел зашел на сайт и проголосовал то больше он не может голосовать в опросе, а если я через месяц создам новые вопросы для опроса, и удалю ip адреса из базы, то происходит каято фигн потомучто он проверяет куки того кто уже голосовал ранее и выводит результат и новое голосование в се вместе, КАК УБРАТЬ ЭТУ ПРОВЕРКУ КУКОВ.
#33 L 21-06-2016 в 17:41
Мои глаза(
#34 Дмитрий 10-12-2016 в 18:59
Здравствуйте! Помогите сделать подобную таблицу только еще проще. Есть добрые люди?))) я вот тут: https://vk.com/radioshansonplus
#35 Игорь 30-12-2016 в 22:48
Скрипт красивый, но как в эту долбаную таблицу добавить свои вопросы? В какое поле их втыкать нужно?
Неужели трудно было это растолковать для несведующих?
#36 Игорь 30-12-2016 в 23:12
Всю голову себе сломал, куда нахрен вставлять в эту базу свои вопросы?

И почему на Денвере выскакивает вот эта ошибка:

Warning: mysql_data_seek() [function.mysql-data-seek]: Offset 0 is invalid for MySQL result index 5 (or the query data is unbuffered) in Z:\home\test1.ru\www\poll\index.php on line 107


#37 Игорь 31-12-2016 в 00:57
Один сплошной блять вырывается, весь выебся! Ты автор, когда выкладываешь информацию, то выкладывай из расчёта, что не все такие умные, как ты и они могут чего-то не знать.
Что ты написал: "поэтому нам понадобится создать таблицу, например, answer и заполним ее вариантами ответов:"

Как это понять можно? Как эту твою таблицу вообще можно заполнить вопросами? Куда и что вставлять?
#38 Алексей 08-01-2017 в 17:19
Полностью поддерживаю Игоря. Сам сижу уже пару дней с этой базой. Причём с базой как таковой проблем нет, делается легко, но она пустая. Вообще не въезжаю, как в неё вставить свои варианты вопросов.
Добавить новый комментарий

Автор:

Текст сообщения:

Если в комментарии присутствует код, пожалуйста вставляете его между тегами [code][/code]

cap

Код с картинки:


Получать уведомления о новых комментариях по Email могут только зарегистрированные пользователи.

41001346159934
R314489888859
Уроки
Для начинающих
Интересное
Файлы
Полезное
Опрос

Много ли среди программистов девушек?

Последние комментарии
Ссылки