Published by Shawn on 13 Apr 2008 at 12:31 pm
Ajax Rating Script using Thumbs Tutorial
Thumber - Ajax / PHP Rating Script II
I made this script because I realized how awful my other Ajax Rating Script code looks!
This is a fairly light-weight, non-degradable
Ajax script for rating a specific item using the “Thumbs Up, Thumbs Down” approach.
The script uses the Prototype Javascript Framework to ligthen the load!
The script is also in object notation (JSON) style / function closure, using a Cookies object and Voter object explained below.
Here’s the Ajaxian thumb rate script example.
I use Behaviour.js to set the onclick events outside of the markup. This sort of separation leads to unobtrusive, degradable javscript, which is pretty damn cool!
Here is the XHTML for the page. The two images are controlled by the CSS. The anchor tags have an onclick event (handled by myrules)that fires Voter’s vote() function.
The input button is for demo only. When pressed, it erases the Cookie that is stored on the client, so you can vote one more time. This is simply for demonstrative purposes.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/2001/REC-xhtml11-20010531/DTD/xhtml11-flat.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Rating Script - Thumbs Up Thumbs Down | Shawngo.com</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8"/>
<link type="text/css" href="thumber.css" rel="stylesheet" media="screen,projection" title="Default Theme" />
<script src="prototype.js" type="text/javascript"></script>
<script src="behaviour.js" type="text/javascript"></script>
<script type="text/javascript" src="voter.js"></script>
<script type="text/javascript" src="cookies.js"></script>
<script type="text/javascript">
// two event handlers .. thumberdown could actually call thumberup..etc
var myrules = {
'.thumberup' : function(element){
element.onclick = function(){
Voter.vote(this.id);
return false;
}
},
'.thumberdown' : function(element){
element.onclick = function(){
Voter.vote(this.id);
return false;
}
}
};
Behaviour.register(myrules);
</script>
</head>
<body>
<div class="thumbs">
<span id="blog1.msg">Rate Me</span>
<ul>
<li class="up"><a id="blog1.up" title="Thumbs Up" class="thumberup" href="fart.html">10</a></li>
<li class="down"><a id="blog1.down" title="Thumbs Down" class="thumberdown" href="fart.html">11</a></li>
</ul>
</div>
<div class="thumbs">
<span id="blog2.msg">Rate Me</span>
<ul>
<li><a id="blog2.up" title="Thumbs Up" class="thumberup" href="fart.html">10</a></li>
<li><a id="blog2.down" title="Thumbs Down" class="thumberdown" href="fart.html">11</a></li>
</ul>
</div>
<div id="result"></div>
<p><input type="button" onclick="Cookies.erase('blog1');" value="Erase cookie"/></p>
<p><input type="button" onclick="Cookies.erase('blog2');" value="Erase cookie"/></p>
</body>
</html>
Nothing fancy here. Just padding out the anchor tag to fit the image and setting font attributes.
.thumbs{
font-family: "Trebuchet MS";
font-size:15px;
font-weight:bold;
border: 3px solid #eee;
padding:0 5px 10px 5px;
width:150px;
text-align:center;
}
.thumbs ul{
padding:0;
margin:0;
}
.thumbs ul li{
display:inline;
}
.thumbs a{
text-decoration:none;
padding:0 5px;
border: 3px solid #feb;
}
a.thumberup{
background:url(up.jpg) top right no-repeat;
padding-right:20px;
}
a.thumberdown{
background:url(down.jpg) top left no-repeat;
padding-left:20px;
}
.thumbs a:hover{
border: 3px solid #feb300;
}
The Voter Class in voter.js.
Clicking on the link, which fires onclick = "Voter.vote('blog1.up');", determines if there is a cookie set for this widget.
If not, the request parameters, pars, are sent to Prototype’s Ajax.Request function.
Otherwise, a message is sent to the client that they have voted.
When the function is complete, it calls Voter.showResponse function which could either substitue for $(what_in).innerHTML = parseInt($(what_in).innerHTML)+1; this line. We could return all sorts of information to relay to the user, but that is beyond the scope of this tutorial. Don’t you hate that?
Voter = {
vote : function(what_in){
var what = what_in.substring(0,what_in.indexOf("."));
var up_down = what_in.substring(what_in.indexOf(".")+1,what_in.length);
var voted = Cookies.read(what);
if(voted == null){
$(what_in).innerHTML = parseInt($(what_in).innerHTML)+1;
this.voted=true;
pars="vote="+up_down+"&what="+what;
Cookies.create(what,"voted",1);
var myAjax = new Ajax.Request( 'vote.php', { method: 'get', parameters: pars, onComplete: this.showResponse })
}else{
$(what+'.msg').innerHTML="You already voted";
}
},
showResponse : function(originalRequest){
$('result').innerHTML = originalRequest.responseText;
}
}
The message sent to the client can also be split into an array. This could be useful for updating several different parts of the page.
To do this in the PHP script, simply separate the response with a bar |, example echo $response1."|".$response2;.
$(’result’).innerHTML = originalRequest.responseText.split(”|”)[0];
$(’some_other_element’).innerHTML = originalRequest.responseText.split(”|”)[1];
}
The Cookies Class in cookies.js.
This is a basic javascript cookie utility class. I found it online and just rewrote it using Object Notation.
Cookies = {
create : function (name,value,days){
if (days){
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
},
read : function read(name){
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++){
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
},
erase : function (name){
this.create(name,"",-1);
}
}
I didn’t do very much on the PHP-side. This just returns the $_GET variables for demonstrative purposes.
This script was intented to be used wherever you want. Just assign the name of the item in the 2nd parameter when calling Voter.vote().
You’ll also need to use PHP (or whichever server-side language you choose) to set the initial value for ‘number of votes’. For this tutorial I have the example set to 10 for both.
Ideally you’d write a simple database query function with a bit of error checking for fun.
<? // do database stuff here // i threw this in here for fun print_r($_GET); // you could also send multiple responses separated by, oh, say, a // then split the response in the javascript.. demonstrated ?>
dustman on 01 May 2008 at 6:50 pm #
how do you get the script to recall and remember the totals in a database?
admin on 01 May 2008 at 9:14 pm #
@dustman - the quickest answer to the first part of your question would be to query the database during the initial page request to get the # of votes. The second part of your question would be to add the functionality to vote.php to handle the incoming POST parameters, validate them, and update the relevant tables.
Something like this might work:
UPDATE articles SET votecount = votecount+1 WHERE articleid = $_POST['articleid']
It is strongly advised that you take any action you feel necessary to validate the user input before the database query.
toto on 27 Jul 2008 at 10:20 pm #
c’est tout bete tu mets un lien “downloader source” et tout le reste on s’en fou..
on est la pour copier/coller ca sert a rien de blablater pour rien dire.
En attendant je sais pas ou recuperer tes sources boufon
remon on 28 Jul 2008 at 3:25 pm #
demo URL is invalid. =(
admin on 30 Aug 2008 at 11:52 am #
Thanks remon - the link has been updated.
Lyme on 03 Oct 2008 at 10:59 am #
Problem with this script is that if cookies are disabled, unlimited votes are possible.
LeoLoe on 26 Oct 2008 at 6:23 pm #
Are links to behaviour.js, prototype.js, and voter.js all invalid?
Shawn on 29 Oct 2008 at 7:18 am #
The library links are indeed broken. I’ll update them soon.