Thumber – Ajax / PHP Rating Script II
Update: I have, if you will, graduated from using Prototype.js and Behaviour.js to using jQuery as my preferred JS library. I’ve also updated a few of the .js links below.
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!
On to the script!
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="#">10</a></li>
<li class="down"><a id="blog1.down" title="Thumbs Down" class="thumberdown" href="#">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="#">10</a></li>
<li><a id="blog2.down" title="Thumbs Down" class="thumberdown" href="#">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>
The CSS!
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 javascript!
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;.
showResponse : function(originalRequest){
$('result').innerHTML = originalRequest.responseText.split("|")[0];
$('some_other_element').innerHTML = originalRequest.responseText.split("|")[1];
}
The javascript!
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);
}
}
The PHP!
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.
<?php
// 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
?>