Featured Posts

Google Chrome makes JavaScript Sexy! Thanks Google! Get SpeedTracer at http://code.google.com/webtoolkit/speedtracer/

Readmore

Shawngo On Flickr Spell On Flickr

Readmore

WP Updated, New Theme, Confusion How do I get items in the Featured Posts carousel? No README.TXT file in the theme, no OBVIOUS theme settings, no wonder I don't use WP! :D Developers like README and INSTALL...

Readmore

Shawngo.com Rss

Ajax Rating Script using Thumbs Tutorial

Posted on : 13-04-2008 | By : Shawn | In : JavaScript, PHP

Tags:

35

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 &lt; 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
 
?>

Comments (35)

how do you get the script to recall and remember the totals in a database?

@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.

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

demo URL is invalid. =(

Thanks remon – the link has been updated.

Problem with this script is that if cookies are disabled, unlimited votes are possible.

Are links to behaviour.js, prototype.js, and voter.js all invalid?

The library links are indeed broken. I’ll update them soon.

Hey,
Where is voter.js script? Any1 knows? thx

Do you have a demo of the script? Thanks

Hi!
I was looking all over for something like this,
The thing is, how do I make the site remember the number os votes and article has??
I need help with this please! :)

great!

This script is great, but when I use it in my website, and I click on a thumb, it says that it can’t find fart.html? What do I do wrong?

@Sadu – I updated the links – they didn’t carry over with the Wordpress install.

@Steve – the demo script is here http://www.shawngo.com/thumber/

@Manuel – Sorry but I guess I never got around to this. If you still need help feel free to drop me a line.

@Peter – your comment is priceless! I don’t know why I left that in there – I’ve updated them to # marks. I believe the Behaviour.js should pick up on the click event on those anchor tags and you shouldn’t be taken to the “fart.html” page.

I would recommend everyone check out http://jquery.com – it’s a great JavaScript library written by a reputable JavaScript Ninja!

Shawn

sweet little blog you have going on here :)

shawngo

i’m confused you say you moved away from prototype and on to jquery but i don’t see any reference to jquery in the above or in the example. in fact int he example page you still call prototype. am i missing something, is there an update example and tutorial?

@Cass thx :)

@phynias – I don’t have a jQuery example for the rating script.. but I play one one TV!

damn….love the script but i can’t use prototype, damn.
you don’t happen to know of another script that uses mootools or jquery?

ps:kind of misleading to mention jquery in this article like that if it isn’t used in it.

@phynias – I think there are a couple here http://tinyurl.com/dfxey8 :)

Do you use a CMS? Drupal, which uses jQuery, has a Voting API module http://drupal.org/project/votingapi

MODx uses MooTools but I haven’t found a voting script but it should be fairly straightforward using snippets and template variables.

nope i don’t use a cms, this would be for a site i coded all myself.

oh and i googled forever. i found a star rating, but none can be easily converted to do a yes/no type rating.

@phynias – I probably should re-code this one. Were you looking for anything in particular? Thumbs Up/Down or Yes/No? I’d suggest checking out Drupal 6.x. It’s a great CMS backed by an awesome community! Let me know – if I have time I might throw something together.

im just looking for thumbs up/down. and i know about drupal, but i am not using a cms nor do i need to.

Can anyone give the full script of ajax rating with thumbs

“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.”

If this is your attempt to get better SEO results then hurray for you… but like we all have already said.. its very misleading.

@aaron – How would I benefit from better SEO results? I have no advertising on this site, I’m not trying to sell anything, I’m not promoting anything, etc… I simply stated that I no longer use those JS libraries. What is it that is misleading?

For your reference, the tagline of this site at time of writing is “Just another WorthLess weblog”

Hi
I am hoping you tell if this can work on a php classified site or is this specific to an application.

Thanks

@Lars – this is more of a demonstration of how to start implementing a rating system. It is a bit outdated with respect to the JavaScript libraries etc. If you’re using a JavaScript library or framework I’d suggest looking for a plug-in for that particular framework. Otherwise, um.. use Drupal! :D

Uhh… whats the point of this? it doesnt even save…..

This bit of code is a GREAT help for those of us who do not program on a regular basis (if at all).

I was wondering if you have a simple piece of php code to push the result of the thumbs up/down back into the database. IE someone vote, the javascript adds one to the tally, and then the new tally gets updated on the database.

Many thanks.

Rgds,

Lily

Shawn is the man and has helped me through my full integration. Like shawn stated at the beginning of the article Nikita, this was created as a demonstration for how you would create a rating script for your site. That was the point and since everyones setup is quite different, this example provides a very general approach towards integration which is awesome I might add. Once you find your way of fitting it into whichever setup you have, then you can look into adding the database entry etc. Thanks again Shawn for all your help!

Shawn, this is one of the first time’s I have ever used javascript to this extent. I’m already very familiar with PHP / MySQL, so I’ve been able to adjust the script to work seamlessly with my database.

However, since I’m so unfamiliar with Javascript I’m having a hard time adjusting the voting script to my needs. I’m looking for a way to command the script to take in a specific part of the innerHtml, rather than the entire contents between the a tags.

For example, my link looks something like this (I’ve indented it for easier reading):

<a id=".up” title=”Thumbs Up” class=”thumberup” href=”#”>
upvote ()

Because the script takes the entire contents,
upvote () ,
It prints Not a Number errors client side, though still registers the vote in the database server side.

Is there some way that I could single out the section so that votes.js returns the updated value properly?

Any help would be appreciated, thanks!

I should have figured this would happen. all empty spaces in the above code samples are php echo units from the database.


upvote ()

all tags are closed properly, etc.

Thanks again!

I guess I should have read these comments before spending so much time tweaking the thumbs. Silly me!

If you want to check out an example of this with an “I LIKE” only look (and maybe help me figure out how to SAVE THE RESULTS.

http://www.golfinggreys.com/nd/minot_TEST.php

Ant help would be much appreciated.

Nice post though – I have learned to read it all now!

@Pasigdesigns – I would suggest scrapping Prototype and Behaviour in favor of jQuery. jQuery just makes things easy! :)

Here’s a tutorial similar to the one above using jquery http://ad1987.blogspot.com/2009/02/reddit-style-voting-with-php-mysql-and.html

Again, I highly recommend switching over to jQuery – I can’t stress this enough! It is practically essential that you also use Firebug – if you don’t know what it is, Google it, install it, learn it and use it!

Happy Coding! :D

Write a comment