Have an account? Sign in
Login  Register  Facebook
Create Dynamic Poll System With Animated Colors
[Edit] jQuery Dynamic Poll With Animated Colors

View It Online

Download

You can download this Tutorial, just go to the files at the bottom
[Edit] The JavaScript
I will use the jQuery framework and 'backgroundColor.js' (remove it if you have the jQuery UI)

Get Color For Percentage

var percentColors = [
    { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
    { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
    { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } } ];

var getColorForPercentage = function (pct) {
        for (var i = 0; i < percentColors.length; i++) {
            if (pct <= percentColors[ i ].pct) {
                var lower = percentColors[i - 1] || {
                    pct: 0.1,
                    color: {
                        r: 0x0,
                        g: 0x00,
                        b: 0
                    }
                };
                var upper = percentColors[ i ];
                var range = upper.pct - lower.pct;
                var rangePct = (pct - lower.pct) / range;
                var pctLower = 1 - rangePct;
                var pctUpper = rangePct;
                var color = {
                    r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
                    g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
                    b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
                };
                return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
            }
        }
    }
This function take a percentage from 0 to 1 (0.10 = 10%, 0.05 = 5% etc) and return a color (0 = red | 1 = green | any percentage in between 0 and 1 wil take its color value between red and green)

The jQuery

$(document).ready(function ($) {
    // set the first colors
    $('div.polls').find('span.option').each(function () {
        $(this).css({
            backgroundColor: getColorForPercentage($(this).attr('title') / 100)
        });
    });
    // the on click event
    $("div.polls > form > p").click(function () {
        var loader = $('<img src="lib/loading.gif" />');

        var poll = $(this).parents("div.polls");
        var form = $(this).parents("form");

        var poll_id = poll.attr("id");

        if (form.hasClass("closed")) {
            return false;
        }
        var option_id = $(this).find('input').val();

        $(":radio", form).hide();
        $("em", $(this)).html(loader).show();
        form.addClass("closed");
        //send the poll id and the selected option id    
        $.post('vote.php', {
            poll: poll_id,
            option: option_id
        }, function (data) {

            $("img", form).remove();
            //set the new options Percentages
            $.each(data.results, function (option, value) {
                $("p#option_" + option).find("span").show().css({
                    width: 0,
                    opacity: 0
                }).animate({
                    width: value + "%",
                    backgroundColor: getColorForPercentage(value / 100),
                    opacity: 1
                }, "slow", "swing", function () {
                    $("p#option_" + option).find("em").text(value + "%").fadeIn("slow");
                })
            });

        }, "json");
        return false;
    });
});

How the background Color work with .animate() ?

as you know, .animate() function never work with the backgound-color, so we use extra code (backgroundColor.js) for this if you use jQuery only but if you have the UI you can use the code without backgroundColor.js
[Edit] The PHP & MYSQL
index.php
<?php
    
    $id = (isset($_GET['id'])) ? intval($_GET['id']) : 1;

    if(!$row = get_poll($id)){
        exit('not found');
    }
    
    
?>
<div id="<?php echo $row['poll_id'];?>" class="polls">
    <h2><?php echo $row['title'];?></h2>
	<form <?php if(get_votes($row['poll_id'])){ echo 'class="closed"';}?> method="post">
    
        <?php
            foreach (poll_options($id) as $option) {
        ?>    
        	<p id="option_<?php echo $option['id'];?>">
        		<span class="option" style="width:<?php echo $option['percent'];?>%;" title="<?php echo $option['percent'];?>"></span>
        		<input id="<?php echo $option['id'];?>" name="vote" value="<?php echo $option['id'];?>" type="radio" />
        		<label for="<?php echo $option['id'];?>"><?php echo $option['title'];?></label>
        		<em><?php echo $option['percent'];?>%</em>
        	</p>            
        <?php    	
            }	
        ?>    

	</form>
</div>
vote.php (to record user's vote)
    if ( isset($_POST['poll']) and isset($_POST['option'])){
        
        $poll_id = intval($_POST['poll']);
        $option_id = intval($_POST['option']);
        
            add_vote( $option_id,$poll_id );
            setcookie('poll_'.$poll_id, 1, time() * (60 * 60 * 5),'/');
            
        exit( json_encode(array('results' => results($poll_id))) );
    }

The functions

this are the functions used in the code

get_poll()

to get the poll row
    function get_poll($id){
        $query = mysql_query("SELECT * FROM `polls` WHERE `poll_id` = '$id'");    
            return mysql_fetch_array($query, MYSQL_ASSOC ); 	
    }

poll_options()

give all answers related to the poll with its percentage
    function poll_options($poll_id){
        $query = mysql_query("SELECT x . * , z.rates 
                                FROM poll_options x
                                    LEFT JOIN (SELECT option_id, COUNT( id ) AS `rates`
                                            FROM poll_votes 
                                                GROUP BY option_id) z 
                                                    ON x.id = z.option_id
                              where x.poll_id = '$poll_id' ORDER BY x.id asc");   
        $total =  total_votes($poll_id);
            while( $row = mysql_fetch_array( $query, MYSQL_ASSOC ) ){   
                $row['percent'] = @round((($row['rates'] / $total) * 100),1);
                $list[] = $row;
            }
       return $list;     
    }

results()

to get just options id with its percentage related to the poll
    function results($poll_id){
        foreach (poll_options($poll_id) as $value) {
        	$list[$value['id']] = $value['percent'];
        }
            return $list;
    } 

total_votes()

get the total votes for specific poll
    function total_votes($poll_id){
    	$query = mysql_query("SELECT sum(z.rates) as total
                                FROM poll_options x
                                    JOIN (SELECT option_id, COUNT( id ) AS `rates`
                                            FROM poll_votes 
                                                GROUP BY option_id) z 
                                                    ON x.id = z.option_id
                              where x.poll_id = '$poll_id'");
            $row = mysql_fetch_array( $query, MYSQL_ASSOC );
                return $row['total'];
    }

get_votes()

check if the user voted or not, by check ip and cookies
    function get_votes($poll_id){
        $query = mysql_query("SELECT * FROM `poll_votes` where `poll_id` = '$poll_id' and `ip` = '{$_SERVER["REMOTE_ADDR"]}'");
           $row = mysql_fetch_array( $query );
           if($row or isset($_COOKIE['p_'.$poll_id])){
                return $row;
           }else{
                return false;
           }    
    }

add_vote()

check if the user already voted or not and then insert or update user vote
    function add_vote($option_id,$poll_id){
        $row = get_votes($poll_id);
            if(!$row){
                mysql_query("INSERT INTO `poll_votes` (`poll_id` ,`option_id` ,`ip`) VALUES ( '$poll_id','$option_id', '{$_SERVER["REMOTE_ADDR"]}')");      
            }else{
                mysql_query("UPDATE `poll_votes` set `option_id` = '$option_id' where `id` = '{$row['id']}'");                               
            }    	
    }
Don’t be Afraid to Ask for Help
It’s only human nature to want to hide the fact that we don’t know much about a certain topic. Nobody likes being a n00b! But how are we going to learn without asking? Feel free to use our problems section to ask more seasoned PHP developers questions.
Poll vote Dynamic September 26, 2011