var url = 'pollhandler.php'; var colors = ['red', 'green', 'blue', 'orange']; $(document).ready(function() { // Intercept form submissions $("form").submit(function() { return false; }); // Handle voting $('#castvote').click(poll_vote); /* Let the user request a new poll (use an anonymous function because poll_fetch takes an optional argument poll_id, and the callback will be passed the object that triggered the event) */ $('#newpoll').click(function () { poll_fetch(); }); }); /* poll_fetch(poll_id) * Fetches poll poll_id via Ajax * If no poll_id is specified, fetches a random poll */ function poll_fetch(poll_id) { $(this).attr('disabled', true).val("Getting new poll..."); if (!poll_id) { $.getJSON(url, null, poll_display); } else { $.getJSON(url, {'poll_id': poll_id}, poll_display); } } /* poll_display(data, textStatus) * Handler that displays a voting form for a poll retrieved by an Ajax call */ function poll_display(data, textStatus) { // Wrap jQuery functionality around the poll DOM element var poll = $("#poll"); // Fade the poll out poll.fadeOut(function() { // Empty the responses poll.find("#responses").empty(); // Update the question poll.find("#question").html(data.question); // Loop through the responses $.each(data.results, function(response_id, response) { // Create a div for this response var responseDiv = $('
').addClass('response'); // Create the input button /* Note: we have to specify the type of the input field when we create it, or else this won't work in IE. See this page for more info: http://msdn2.microsoft.com/en-us/library/ms534700.aspx */ var responseButton = $('').attr( {'name': 'vote', 'value': response_id, 'id': 'response-' + response_id} ).appendTo(responseDiv); // Create a form label with the response text var responseText = $('').attr('for', 'response-' + response_id).html(response.response).appendTo(responseDiv); /* Append the div to the responses container (and thus show it on the page) */ $("#poll > #responses").append(responseDiv); }); // Create an input element to store the poll id, and append it var inputPollId = $('').attr('name', 'poll_id').val(data.poll_id); $("#poll > #responses").append(inputPollId); // Enable and show the voting button $("#castvote").attr('disabled', false).val("Vote").show(); // Re-enable the get new poll button $("#newpoll").attr('disabled', false).val("Get new poll"); // Fade the poll in poll.fadeIn(); }); } /* poll_results(data, textStatus) * Handler that displays the results for a poll retrieved by an Ajax call */ function poll_results(data, textStatus) { var question = data.question; var pollResponses = $("#poll > #responses"); // Fade the responses out pollResponses.fadeOut(function() { // Empty the responses pollResponses.empty(); // Determine total, highest vote counts var total_votes = 0; var max_votes = 0; $.each(data.results, function() { total_votes += this.votes; max_votes = Math.max(this.votes, max_votes); }); // Loop through the responses var i = 0; $.each(data.results, function(response_id, response) { /* Create a div for the result, and give it the text of the response/vote count */ var responseDiv = $('').addClass('result').attr('id', 'response-' + response_id).html(response.response + ' (' + response.votes + ')'); /* Create a container for the vote bar (to give it some height even when it's hidden) */ var container = $('').addClass('votebarContainer').appendTo(responseDiv); // Create the vote bar var responseVotes = $('').addClass('votebar ' + colors[i % colors.length]).width(0).hide().appendTo(container); /* Calculate the percent of votes for this response and the size to make the poll bar */ var responseVotePercent; var barWidth; var responseVoteCount = $('').addClass('votepercent'); if (total_votes == 0) // avoid divide by 0 { responseVotePercent = 0; barWidth = 0; responseVoteCount.text(responseVotePercent + "%").appendTo(responseDiv); } else { responseVotePercent = (Math.round(response.votes / total_votes * 10000) / 100); barWidth = response.votes / total_votes / (max_votes / total_votes) * 100; responseVoteCount.text(responseVotePercent + "%").appendTo(responseVotes); } // Append the result to the responses container $("#poll > #responses").append(responseDiv); // Find the pixel width of our container (our max pollbar width) var barWidthPx = container.width(); /* Queue up the animation, using the maximum bar size to determine how long this particular animation should take place. */ responseVotes.queue(function() { $(this).animate({width: barWidth + "%"}, {duration: 1500*(barWidth/100), easing: 'linear', step: function (e, obj) { /* The step attribute lets us specify a function that runs for each step of the animation. Here, we use it to update the percent value on the bar as it grows in size. */ if (responseVotePercent == 0) // div by 0 { pollbar_set(0, responseVoteCount); } else { pollbar_set(responseVotePercent * (obj.now / obj.end), responseVoteCount); } }}); }); i++; }); // Hide the vote button from view $("#castvote").hide(); // Display the total number of votes var totalVotesDiv = $('').addClass('totalvotes').text('Total votes: ' + total_votes).appendTo('#poll > #responses'); /* Now fade in the responses, and once that's done, dequeue (run) all of the animations that we queued. */ pollResponses.fadeIn(function () { pollResponses.find(".votebar").dequeue(); }); }); } /* pollbar_set(percent, object) * Sets the text of a jQuery object to be "percent%", rounded to * two decimal places. */ function pollbar_set(percent, object) { var percentDisplay = (Math.round(percent * 100) / 100); object.text(percentDisplay + "%"); } /* poll_vote() * Casts a vote via Ajax and displays the results * If no choice was selected, just display the results */ function poll_vote() { // Determine the poll id var poll_id = $("form input:hidden[name=poll_id]").val(); // Determine what the person voted for (if anything) var vote; var voteField = $("form input:radio:checked"); if (voteField.length < 1) { vote = ''; } else (voteField.length == 1) { vote = voteField.val(); } // Send our vote via POST, and prepare for a response in JSON $.post(url, {'poll_id': poll_id, 'vote': vote}, poll_results, 'json'); // Disable the voting button (to prevent multiple clicks) $("#castvote").attr('disabled', true).val("Voting..."); }