Сегодня мы будем учиться созданию перетаскиваемого опросника, который позволит нашим посетителям выбирать их самые любимые статьи на сайте. Затем они будут голосовать, а созданная на CSS диаграмма покажет общий рейтинг опроса.
Для того, чтобы реализовать это, нам потребуется использовать jQuery, jQuery UI, PHP, CSS и MySQL.
Вы можете использовать код с нашей статьи, чтобы потом дорабатывать его и делать собственные версии: demo.zip [16,41 Kb] (cкачиваний: 193)
Этап 1 – XHTML
Для лучшего понимания того, что мы делаем, вам было бы неплохо скачать файлы и иметь их под рукой, желательно открытыми. Так вы сможете отслеживать код, о котором мы будем рассказывать.
Начнем с верстки XHTML. Большая часть кода программными методами добавлена на PHP. Ниже приведем часть из файла demo.php:
demo.php
<div id="main">
<?php /* ... */ ?>
<div class="clear"></div>
<!-- The form below is not directly available to the user --> <form action="?results" id="sform" method="post"> <input name="sortdata" id="sortdata" type="hidden" value="" /> </form>
Стоит обратить внимание на форму sform. Она содержит в себе отдельное скрытое текстовое поле – sortdata. Оно заполняется с помощью jQuery, как только мы нажимаем кнопку ответа в опросе, и заполняется информацией о расположении и унификации идентификационных номеров статей, которые мы сортируем в опросе. Позже мы вернемся к этому моменту.
Наверное, самая интересная часть в PHP здесь, это строки с 3 по 5. Они отвечают за управление генерацией сортируемых пунктов списка и за образование диаграммы. Ниже мы включили только верстку XHTML, с помощью которой создается список. Мы еще рассмотрим подробнее оставшуюся часть кода в разделе о PHP.
<li id="<?php echo $row['id']?>">
<div class="tut"> <div class="tut-img"> <img src="<?php echo $row['img']?>" width="100" height="100" alt="<?php echo $row['title']?>" /> <div class="drag-label"></div> </div>
<div class="tut-title"> <a href="<?php echo $row['url']?>" target="_blank" title="Open it in a new window!"><?php echo $row['title']?></a> </div>
<div class="tut-description"><?php echo $row['description']?></div>
<div class="clear"></div>
</div> </li>
Этот код расположен в цикле, который извлекает его для каждого пункта списка. И так как мы включили несколько значений echo, это позволяет нам добавить динамическую информацию. В данном случае заголовки и ссылки, которые извлекаются из базы данных.
Теперь давайте рассмотрим подробнее стили CSS.
Этап 2 – CSS
В тексте, приведенном ниже, вы можете наблюдать, как оформляется тот XHTML, который мы сгенерировали ранее. Из-за длины кода, мы включили только конкретно то, что используется в опросе. Вы можете посмотреть остальной код, который используется для оформления демо-страницы, в файле demo.css
demo.css – часть 1
.tut-title{ font-size:20px; font-weight:bold; } .tut-description{ color:#DDDDDD; font-family:Arial,Helvetica,sans-serif; font-size:11px; padding-top:5px; } .tut-img{ border:1px solid white; float:left; margin:0 15px 0 0; width:100px; height:100px; overflow:hidden; /* CSS3 Box Shadow */ -moz-box-shadow:2px 2px 3px #333333; -webkit-box-shadow:2px 2px 3px #333333; box-shadow:2px 2px 3px #333333; cursor:n-resize; position:relative; } .drag-label{ /* The DRAG label that scrolls into visibility on hover */ background:url(img/label_small.png) no-repeat; width:71px; height:25px; position:relative; margin-left:25px; } a.button{ /* The pretty buttons on the bottom are actually hyperlinks.. */ color:#434343 !important; display:block; float:left; font-size:10px; font-weight:bold; height:23px; margin:10px; padding:12px 10px 0 12px; position:relative; text-shadow:none; text-transform:uppercase; /* This is the left part of the button background image */ background:transparent url(img/button_gray_bg.png) no-repeat; } a.button:hover{ text-decoration:none !important; background-position:bottom left; } a.button:active{ /* Offsetting the text 1px to the bottom on mouse-click*/ padding-top:13px; height:22px; } a.button span{ /* This span holds the right part of the button backgound */ background:transparent url(img/button_gray_bg.png) no-repeat right top; height:35px; position:absolute; right:-2px; top:0; width:10px; display:block; } a.button:hover span{ background-position:bottom right; }
В этом коде использованы некоторые интересные ходы и свойства. Одно из них представляет собой значение CSS3 - box-shadow, оно добавляет тень к каждой миниатюре.
На изображении ниже, вы можете посмотреть, как мы оформили кнопки подтверждения и результатов.
demo.css – часть 2
.button-holder{ padding-left:107px; } ul.sort{ /* This UL gets converted to a sortable by jQuery */ font-family:"Myriad Pro",Arial,Helvetica,sans-serif; font-size:20px; } ul.sort li{ margin:25px 50px 25px 0; height:102px; list-style:none; } .chart{ /* Styling the chart container */ background:#002A3C; border:1px solid #005A7F; height:300px; width:550px; } .bar{ /* Each bar in the chart is a div. Colors and width are assigned later */ height:17px; margin:15px; overflow:hidden; padding:15px 10px 10px; text-shadow:none; white-space:nowrap; } .bar a, .bar a:visited{ color:white; font-size:12px; } .tot-votes{ float:right; font-size:10px; font-weight:bold; position:relative; right:50px; text-transform:uppercase; top:18px; }
В этой части кода у нас располагаются классы, с помощью которых оформлена диаграмма. Как вы можете видеть, здесь у нас не указаны ни цвет ни длина полосок, это потому что данные значения генерируются соответственно позиции в опросе. Позже мы вернемся к этому моменту.
Этап 3 – PHP
PHP генерирует сортируемые элементы списка, поддерживает связь с базой данных и генерирует диаграмму.
Ниже вы можете видеть код, о котором мы уже упоминали раннее. Сначала он извлекает все объекты из базы, а потом сортирует список.
demo.php
// Checking whether the user has voted today: $voted=false; $vcheck=mysql_query(" SELECT 1 FROM sort_votes WHERE ip='".$_SERVER['REMOTE_ADDR']."' AND date_submit=CURDATE()"); if(mysql_num_rows($vcheck)==1) $voted=true; // If we are not on the data.php?results page: if(!array_key_exists('results',$_GET)) { echo '<ul class="sort">'; // Showing the tutorials by random $res = mysql_query("SELECT * FROM sort_objects ORDER BY RAND()"); while($row=mysql_fetch_assoc($res)) {?> <li id="<?php echo $row['id']?>"> <div class="tut"> <div class="tut-img"> <img src="<?php echo $row['img']?>" width="100" height="100" alt="<?php echo $row['title']?>" /> <div class="drag-label"></div> </div> <div class="tut-title"> <a href="<?php echo $row['url']?>" target="_blank" title="Open it in a new window!"><?php echo $row['title']?></a> </div> <div class="tut-description"><?php echo $row['description']?></div> <div class="clear"></div> </div> </li> <?php } ?> </ul> <div class="button-holder"> <?php if(!$voted):?><a href="" id="submitPoll" class="button">Submit Poll<span></span></a><?php endif;?> <a href="?results" class="button">View The Results<span></span></a> </div> <?php } else require "results.php"; // The above require saves us from having to create another separate page
Как только пользователь пересортировал значения и подтвердил форму, results.php динамически встраивается в страницу с использованием требуемой функции.
results.php
// If the poll has been submitted: if($_POST['sortdata']) { // The data arrives as a comma-separated string, // so we extract each post ids: $data=explode(',',$_POST['sortdata']); // Getting the number of objects list($tot_objects) = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM sort_objects")); if(count($data)!=$tot_objects) die("Wrong data!"); foreach($data as $k=>$v) { // Building the sql query: $str[]='('.(int)$v.','.($tot_objects-$k).')'; } $str = 'VALUES'.join(',',$str); // This will limit voting to once a day per IP: mysql_query(" INSERT INTO `sort_votes` (ip,date_submit,dt_submit) VALUES ('".$_SERVER['REMOTE_ADDR']."',NOW(),NOW())"); // If the user has not voted before today: if(mysql_affected_rows($link)==1) { mysql_query(' INSERT INTO `sort_objects` (id,votes) '.$str.' ON DUPLICATE KEY UPDATE votes = votes+VALUES(votes)'); } } // Selecting the sample tutorials and ordering // them by the votes each of them received: $res = mysql_query("SELECT * FROM sort_objects ORDER BY votes DESC"); $maxVote=0; $bars=array(); while($row=mysql_fetch_assoc($res)) { $bars[]=$row; // Storing the max vote, so we can scale the bars of the chart: if($row['votes']>$maxVote) $maxVote = $row['votes']; }
$barstr=''; // The colors of the bars: $colors=array('#ff9900','#66cc00','#3399cc','#dd0000','#800080'); foreach($bars as $k=>$v) { // Buildling the bar string: $barstr.=' <div class="bar" style="width:'.max((int)(($v['votes']/$maxVote)*450),100).'px;background:'.$colors[$k].'"> <a href="'.$v['url'].'" title="'.$v['title'].'">'.$v['short'].'</a> </div>'; } // The total number of votes cast in the poll: list($totVotes) = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM sort_votes"));
Как только опрос подтвержден, скрипт извлекает порядковые номера (ID) сортируемых значений и добавляет от 1 до 5 голосов к каждому, в зависимости от его позиции. Далее новые голоса добавляются к таблице sort_objects.
Важно ограничить возможность голосования до одного раза в день. Именно для этого мы вносим новую строку в таблицу sort_votes каждый раз, как пользователь оставляет голос.
Специфичность этой таблицы в том, что она раздает определенные ключи на каждый IP. Это значит, что MySQL выдаст ошибку, если мы попытаемся сдублировать строку в таблице, что означает, что голоса лимитированы для каждого IP.
Следующее о чем мы упоминали, это о том, как генерируются полосы. Вы можете видеть, что мы задали два значения CSS в атрибуты полосы – ширина и цвет фона. Они добавляются динамически, в зависимости от количества голосов, как видно по 59-й линии.
Дальше мы сгенерировали переменную $barstr, которая отображается на странице, после того как будет готова диаграмма.
 Этап 4 – jQuery
До того, как начать работать с jQuery, нам нужно внести все требуемые файлы. В данной статье, мы используем сразу и библиотеку jQuery и jQuery UI (для сортируемого списка), поэтому нам нужно добавить оба файла, а также наши собственные script.js и таблицу стилей.
demo.php
<link rel="stylesheet" type="text/css" href="demo.css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script> <script type="text/javascript" src="script.js"></script>
Итак, о каком сортируемом списке мы говорим?
Специальный компонент jQuery UI (который в основном фокусируется на интерфейсах и является дополнением к основной библиотеке jQuery), который позволяет разработчикам конвертировать любой упорядоченный и неупорядоченный список (OL/UL) в компонент интерфейса сортируемого списка с возможностью перетаскивания. Библиотека также предоставляет способ получения упорядочивания элементов в javascript, который вы сможете применить позже.
Все довольно просто, на самом деле.
Теперь давай посмотрим, как это устроено.
script.js
$(document).ready(function(){ // Executed once all the page elements are loaded // Convert the UL with all the tutorials into a sortable list: $("ul.sort").sortable({ handle : '.tut-img', // We provide the thumbnails as drag handles axis:'y', containment: 'document', // The elements cannot be dragged outside the document opacity: 0.6 }); // The hover method takes a mouseover and a mouseout function: $(".tut").hover( function(){ $(this).find('.drag-label').stop().animate({marginTop:'-25px'},'fast'); }, function(){ $(this).find('.drag-label').stop().animate({marginTop:'0'},'fast'); } ); // Binding an action to the submitPoll button: $('#submitPoll').click(function(e){ // We then turn the sortable into a comma-separated string // and assign it to the sortdata hidden form field: $('#sortdata').val($('ul.sort').sortable('toArray').join(',')); // After this we submit the form: $('#sform').submit(); // Preventing the default action triggered by clicking on the link e.preventDefault(); }); });
Да, все очень просто – просто воспользуйтесь sortable() с некоторыми опциями и все готово.
Дальше мы просто берем порядок элементов с sortable('toArray'), что и выстраивает элементы списка в тот порядок, в который они отсортированы.
После нажатия кнопки подтверждения ответа мы берем данные вышеупомянутым методом, добавляем их в строку, и заверяем в поле sortdata в форме sform, которое далее подтверждается в results.php.
Этап 5 – MySQL
Если вы рассчитываете запустить это демо на локальном компьютере, убедитесь в том, что вы создали таблицы sort_votes и sort_objects в базе данных MySQL. И дальше укажите параметры подключения в файле connect.php.
Вы можете запустить код из tables.sql в вашем любимом менеджере баз данных (например, PHPMyAdmin) и эти две таблицы создадутся автоматически.
И на этом мы закончили работу на нашим опросником! Посмотреть демо опроса в работе.
Заключение
Сегодня мы использовали jQuery и способ сортировки, создали забавную диаграмму с помощью небольшого кода PHP и CSS, и продемонстрировали некоторые взаимодействия с базами данных.
А теперь вы можете делать с этим кодом и знаниями все что хотите!
Вернуться назад
|