Voting System Youtube Style With jQuery & PHP
Voting system can be important part of any website, especially if you want to keep track of user ratings. Let's create a cookie based voting system, similar to YouTube like & dislike buttons (Thumbs up & Thumbs down), which can be applied to any content. We will assign Unique ID(s) to each voting block, these Unique IDs will play important role here, we will be updating and inserting database records, and identifying user votes based on it. Let's create a 4 columns table in MySql Database.SQL
- 1
- 2
- 3
- 4
- 5
- 6
- 7
CREATE TABLE IF NOT EXISTS `voting_count` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`unique_content_id` varchar(100) NOT NULL,
`vote_up` int(11) NOT NULL,
`vote_down` int(11) NOT NULL,
PRIMARY KEY (`id`)
);
Style
This is our CSS, this should go within head tag or in a CSS file.CSS
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
<style type="text/css">
/*voting style */
.voting_wrapper {display:inline-block;margin-left: 20px;}
.voting_wrapper .down_button {background: url(images/thumbs.png) no-repeat;float: left;height: 14px;width: 16px;cursor:pointer;margin-top: 3px;}
.voting_wrapper .down_button:hover {background: url(images/thumbs.png) no-repeat 0px -16px;}
.voting_wrapper .up_button {background: url(images/thumbs.png) no-repeat -16px 0px;float: left;height: 14px;width: 16px;cursor:pointer;}
.voting_wrapper .up_button:hover{background: url(images/thumbs.png) no-repeat -16px -16px;;}
.voting_btn{float:left;margin-right:5px;}
.voting_btn span{font-size: 11px;float: left;margin-left: 3px;}
</style>
HTML markup
Paste following HTML code in your page anywhere you want voting system to appear, I have inserted the code inside header <h3> --- </h3>. Replace each block ID XXXXXXX with unique number or string, Unique ID should not match with each other.HTML
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
<!-- voting markup -->
<div class="voting_wrapper" id="XXXXXXX">
<div class="voting_btn">
<div class="up_button"> </div><span class="up_votes">0</span>
</div>
<div class="voting_btn">
<div class="down_button"> </div><span class="down_votes">0</span>
</div>
</div>
<!-- voting markup end -->
jQuery
On page load, we will fetch vote counts from database into <span class="up_votes"></span> and <span class="up_down"></span> elements. Using jQuery.each() we can loop through each voting block to collect Unique IDs. These IDs are required to fetch vote counts for each voting block. Since we need to fill two values here, it is good idea to fetch JSON data. (See vote_process.php for PHP json_encode() usage). Take a look at code below:JQUERY
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
//####### on page load, retrive votes for each content
$.each( $('.voting_wrapper'), function(){
//retrive unique id from this voting_wrapper element
var unique_id = $(this).attr("id");
//prepare post content
post_data = {'unique_id':unique_id, 'vote':'fetch'};
//send our data to "vote_process.php" using jQuery $.post()
$.post('vote_process.php', post_data, function(response) {
//retrive votes from server, replace each vote count text
$('#'+unique_id+' .up_votes').text(response.vote_up);
$('#'+unique_id+' .down_votes').text(response.vote_down);
},'json');
});
JQUERY
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
$(".voting_wrapper .voting_btn").click(function (e) {
//get class name (down_button / up_button) of clicked element
var clicked_button = $(this).children().attr('class');
//get unique ID from voted parent element
var unique_id = $(this).parent().attr("id");
if(clicked_button==='down_button') //user disliked the content
{
//prepare post content
post_data = {'unique_id':unique_id, 'vote':'down'};
//send our data to "vote_process.php" using jQuery $.post()
$.post('vote_process.php', post_data, function(data) {
//replace vote down count text with new values
$('#'+unique_id+' .down_votes').text(data);
//thank user for the dislike
alert("Thanks! Each Vote Counts, Even Dislikes!");
}).fail(function(err) {
//alert user about the HTTP server error
alert(err.statusText);
});
}
else if(clicked_button==='up_button') //user liked the content
{
//prepare post content
post_data = {'unique_id':unique_id, 'vote':'up'};
//send our data to "vote_process.php" using jQuery $.post()
$.post('vote_process.php', post_data, function(data) {
//replace vote up count text with new values
$('#'+unique_id+' .up_votes').text(data);
//thank user for liking the content
alert("Thanks! For Liking This Content.");
}).fail(function(err) {
//alert user about the HTTP server error
alert(err.statusText);
});
}
});
//end
Process User Votes
Here's our complete vote_process.php file. This PHP code retrieves Ajax POST variables from voting system page, and $_POST["vote"] variable is used to determine what action should be performed next.Since this is a cookie based voting, script sets a cookie after each user vote and prevents user from voting again until the cookie expires.PHP
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
<?php
####### db config ##########
$db_username = 'xxxxx';
$db_password = 'xxxxx';
$db_name = 'xxxxx';
$db_host = 'localhost';
####### db config end ##########
if($_POST)
{
### connect to mySql
$sql_con = mysqli_connect($db_host, $db_username, $db_password,$db_name)or die('could not connect to database');
//get type of vote from client
$user_vote_type = trim($_POST["vote"]);
//get unique content ID and sanitize it (cos we never know).
$unique_content_id = filter_var(trim($_POST["unique_id"]),FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
//Convert content ID to MD5 hash (optional)
$unique_content_id = hash('md5', $unique_content_id);
//check if its an ajax request, exit if not
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
die();
}
switch ($user_vote_type)
{
##### User liked the content #########
case 'up':
//check if user has already voted, determined by unique content cookie
if (isset($_COOKIE["voted_".$unique_content_id]))
{
header('HTTP/1.1 500 Already Voted'); //cookie found, user has already voted
exit(); //exit script
}
//get vote_up value from db using unique_content_id
$result = mysqli_query($sql_con,"SELECT vote_up FROM voting_count WHERE unique_content_id='$unique_content_id' LIMIT 1");
$get_total_rows = mysqli_fetch_assoc($result);
if($get_total_rows)
{
//found record, update vote_up the value
mysqli_query($sql_con,"UPDATE voting_count SET vote_up=vote_up+1 WHERE unique_content_id='$unique_content_id'");
}else{
//no record found, insert new record in db
mysqli_query($sql_con,"INSERT INTO voting_count (unique_content_id, vote_up) value('$unique_content_id',1)");
}
setcookie("voted_".$unique_content_id, 1, time()+7200); // set cookie that expires in 2 hour "time()+7200".
echo ($get_total_rows["vote_up"]+1); //display total liked votes
break;
##### User disliked the content #########
case 'down':
//check if user has already voted, determined by unique content cookie
if (isset($_COOKIE["voted_".$unique_content_id]))
{
header('HTTP/1.1 500 Already Voted this Content!'); //cookie found, user has already voted
exit(); //exit script
}
//get vote_up value from db using unique_content_id
$result = mysqli_query($sql_con,"SELECT vote_down FROM voting_count WHERE unique_content_id='$unique_content_id' LIMIT 1");
$get_total_rows = mysqli_fetch_assoc($result);
if($get_total_rows)
{
//found record, update vote_down the value
mysqli_query($sql_con,"UPDATE voting_count SET vote_down=vote_down+1 WHERE unique_content_id='$unique_content_id'");
}else{
//no record found, insert new record in db
mysqli_query($sql_con,"INSERT INTO voting_count (unique_content_id, vote_down) value('$unique_content_id',1)");
}
setcookie("voted_".$unique_content_id, 1, time()+7200); // set cookie that expires in 2 hour "time()+7200".
echo ($get_total_rows["vote_down"]+1);//display total disliked votes
break;
##### respond votes for each content #########
case 'fetch':
//get vote_up and vote_down value from db using unique_content_id
$result = mysqli_query($sql_con,"SELECT vote_up,vote_down FROM voting_count WHERE unique_content_id='$unique_content_id' LIMIT 1");
$row = mysqli_fetch_assoc($result);
//making sure value is not empty.
$vote_up = ($row["vote_up"])?$row["vote_up"]:0;
$vote_down = ($row["vote_down"])?$row["vote_down"]:0;
//build array for php json
$send_response = array('vote_up'=>$vote_up, 'vote_down'=>$vote_down);
echo json_encode($send_response); //display json encoded values
break;
}
}
?>