JavaScript >> Javascript 文檔 >  >> Tags >> CSS

排序和投票 - 一個 jQuery 投票

今天我們要做一個可拖動的排序和投票投票,這將使我們的網站訪問者能夠從網站上選擇他們最喜歡的教程。在他們投票後,一個友好的 CSS 圖表將向他們展示教程的排名和投票者總數。

為此,我們將使用 jQuery , jQuery UI , PHP , CSS &MySQL .

您可以使用我在此處提供的代碼來製作您自己的版本和混搭。

第 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 填充,並保存一個字符串,表示我們正在排序的教程的排序和唯一 ID。我們稍後會回到這個問題。

也許更有趣的是第 3-5 行的 PHP 部分。它包含處理可排序列表項的生成和圖表的創建的代碼。我在下面只包含了用於構建列表的 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>

此代碼位於 while 循環內,為每個列表項輸出它。因為我們已經包含了一些 echo -s,這允許我們插入動態數據,在本例中是從數據庫中提取的標題和 url。

現在讓我們深入研究一下 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 使用 require 動態包含在頁面中 功能。

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 s 的可排序條目,並根據其位置為每個條目添加 1-5 票。稍後新的投票被添加到 sort_objects 表。

重要的是,用戶每天只能投票一次。這就是我們在 sort_votes 中插入新行的原因 每次用戶提交表單時的表格。

這張表的特別之處在於它在 ip 和 date 字段上定義了一個唯一鍵。這意味著如果我們嘗試在表中插入重複的行,從而限制每個 IP 的投票數,MySQL 將拋出錯誤。

前面提到的另一件事是我們如何生成條形圖。可以看到我們在bar的style屬性中分配了兩個CSS屬性——一個width 和一個背景 顏色。它們是根據票數動態分配的,從第 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 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') 對元素進行排序 .它的作用是返回所有 id s 列表元素按照它們的排序順序。

提交投票 按下按鈕,我們通過上述方法獲取數據,將其連接成一個字符串,並將其分配給 sortdata 表單中的字段 稍後提交到 results.php 的表單 .

第 5 步 - MySQL

如果您打算自己運行此演示,請確保創建 sort_votessort_objects MySQL 數據庫中的表,然後在 connect.php 中填寫您的連接詳細信息 .

您可以從 tables.sql 執行代碼 在您最喜歡的數據庫管理器(例如 PHPMyAdmin)中,這兩個表將自動創建。

至此,我們的可拖動排序和投票投票就完成了!

結論

今天我們使用jQuery和sortable方法,用一點PHP和CSS做了一個漂亮的圖表,並演示了一些有趣的數據庫交互。

您可以在自己的站點中自由使用生成的代碼。該腳本可以輕鬆修改以滿足幾乎任何需求。

還請務必查看我們的 twitter 提要 - 每隔一段時間,我們都會分享一些鏈接,這些鏈接指向由社區創建並受我們教程啟發的精彩內容。


Tutorial JavaScript 教程
  1. 我創建了一個機器人來解決 Wordle,所以我再也不用

  2. 在 Angular 中將圖像 url 轉換為 base64

  3. JavaScript 函數未定義

  4. React 國際化 - 全球化你的 React 應用程序

  5. 設置 React 環境,第 4 部分

  6. 使用 RainbowKit 和 React 製作漂亮的 Connect Wallet 按鈕

  7. 二和

  1. 如何使用 chrome 進行數據抓取 - 數據科學

  2. 邊緣如何啟用關於彈出窗口的可調整大小

  3. 有沒有辦法在 Javascript 中顯示多行字符串?

  4. 如何逃離異步/等待地獄

  5. 在 Angular 中創建數據存儲

  6. 如何:製作 Chrome 擴展程序

  7. 如何將 Material-UI 添加到現有的 Reactjs 應用程序

  1. 使用 UI、Hooks、Context、React-Hook-Form 和 Yup 將任何表單變成步進式表單嚮導

  2. 使用 React 擴展原子設計

  3. 使用 Typescript 構建現代 MUSH 第 5 部分:殺死數據野獸!

  4. CSS漸變生成器