Star Rating Script for YUI
I wanted to have an easy to use star rating script similar to Wil Stuckleys one for jQuery but for YUI. Because I couldn’t find one, I made it myself.
It’s very simple and fully degradable. It works without JavaScript and it notifies about the status of the submission. See example below.
Full disclosure: I’m not very experienced with JavaScript or YUI. I’m quite certain that the code below can be refined in some ways, but as for now, it works for me. If you have any suggestions or comments, please share them! Updated revisions are more than likely :)
Example
With JavaScript
Without JavaScript
Features
- Works with or without JavaScript
- Shows average rating
- Shows status message during and after the submit
- Easy to use
How to use it
Using this script is very easy. Just format your rating form like this:
<div id="ratingdiv">
<form id="rating" action="/path/to/your/controller/" method="post" title="Average: 3.4">
<label for="id_rating">Rating:</label>
<select name="rating" id="id_rating">
<option value="1">1 - Poor</option>
<option value="2">2 - Fair</option>
<option value="3">3 - Good</option>
<option value="4">4 - Very Good</option>
<option value="5">5 - Excellent</option>
</select>
<input type="submit" value=" Submit rating" />
</form>
</div>
and include necassary JavaScript to the page:
<script type="text/javascript" src="/path/to/yui/build/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/path/to/yui/build/dom/dom-min.js"></script>
<script type="text/javascript" src="/path/to/yui/build/event/event-min.js"></script>
<script type="text/javascript" src="/path/to/yui/build/connection/connection-min.js"></script>
<script type="text/javascript" src="/path/to/yui/build/animation/animation-min.js"></script>
<script type="text/javascript" src="rating.js"></script>
For decorating the form, use CSS. This is an example:
<style type="text/css">
<!--
form.rating {
padding: 1em;
border: 1px solid #ccc;
}
.rating {
cursor: pointer;
clear: both;
display: block;
}
.rating:after {
content: '.';
display: block;
height: 0;
width: 0;
clear: both;
visibility: hidden;
}
.star {
float: left;
width: 17px;
height: 15px;
overflow: hidden;
text-indent: -999em;
cursor: pointer;
}
.star,
.star a {background: url(http://media.unessa.net/django/img/projects/star-rating/star.gif) no-repeat 0 0px;}
.star a {
display: block;
width: 100%;
height: 100%;
background-position: 0 0px;
}
div.rating div.on a {
background-position: 0 -16px;
}
div.rating div.hover a,
div.rating div a:hover {
background-position: 0 -32px;
}
div.notifytext {
margin-top: 5px;
font-size: .8em;
clear: both;
}
#ratingdiv {
height: 35px;
}
-->
</style>
xhr that is set to true when the POST is done with JavaScript.
For the first displaying of the form, provide an average rating to the title-attribute of the form. The script assumes it to be in one digit accuracy.
The code
The rating.js looks like this:
var rating = {
init: function() {
rating.ratingform = document.getElementById('rating')
rating.ratingdiv = document.getElementById('ratingdiv')
rating.stardiv = document.createElement('div')
rating.notifytext = document.createElement('div')
rating.average = rating.ratingform.title.split(/:\s*/)[1].split(".")
rating.submitted = false
rating.make_stardiv()
},
make_stardiv: function() {
/* Replaces original form with the star images */
YAHOO.util.Dom.setStyle(rating.ratingform, 'display', 'none');
YAHOO.util.Dom.addClass(rating.stardiv, 'rating');
// make the stars
for (var i=1; i<=5; i++) {
// first, make a div and then an a-element in it
var star = document.createElement('div');
star.id = 'star' + i;
var a = document.createElement('a');
a.href = '#' + i;
a.innerHTML = i;
YAHOO.util.Dom.addClass(star, 'star');
star.appendChild(a);
rating.stardiv.appendChild(star);
// add needed listeners to every star
YAHOO.util.Event.addListener(star, 'mouseover', rating.hover_star, i);
YAHOO.util.Event.addListener(star, 'mouseout', rating.reset_stars);
YAHOO.util.Event.addListener(star, 'click', rating.submit_rating, i);
}
rating.ratingdiv.appendChild(rating.stardiv);
// show the average
rating.reset_stars();
// add the statustext div and hide it
YAHOO.util.Dom.addClass(rating.notifytext, 'notifytext');
YAHOO.util.Dom.setStyle(rating.notifytext, 'opacity', 0);
rating.ratingdiv.appendChild(rating.notifytext);
},
hover_star: function(e, which_star) {
/* hovers the selected star plus every star before it */
for (var i=1; i<=which_star; i++) {
var star = document.getElementById('star' + i);
var a = star.firstChild;
YAHOO.util.Dom.addClass(star, 'hover');
YAHOO.util.Dom.setStyle(a, 'width', '100%');
}
},
reset_stars: function() {
/* Resets the status of each star */
// if form is not submitted, the number of stars on depends on the
// given average value
if (rating.submitted == false) {
var stars_on = rating.average[0];
if (rating.average[1] >= 0)
stars_on = parseInt(rating.average[0]) + 1;
var last_star_width = rating.average[1] + '0%';
} else {
// if the form is submitted, then submitted number stays on
var stars_on = rating.submitted;
var last_star_width = '100%';
}
// cycle trought 1..5 stars
for (var i=1; i<=5; i++) {
var star = document.getElementById('star' + i);
var a = star.firstChild;
// first, reset all stars
YAHOO.util.Dom.removeClass(star, 'hover');
YAHOO.util.Dom.removeClass(star, 'on');
// for every star that should be on, turn them on
if (i<=stars_on && !YAHOO.util.Dom.hasClass(star, 'on'))
YAHOO.util.Dom.addClass(star, 'on');
// and for the last one, set width if needed
if (i == stars_on)
YAHOO.util.Dom.setStyle(a, 'width', last_star_width);
}
},
submit_rating: function(e, num) {
// If the form has not been submitted yet
// and submission is not in progress
if (rating.submitted == false) {
rating.submitted = num;
// After the form is submitted, instead of old average, show
// submitted number of stars selected
rating.average = [num, 0];
// change the statustext div and show it
rating.notifytext.innerHTML = 'Rating is being saved.';
var notify_display = new YAHOO.util.Anim(rating.notifytext, { opacity: { to: 1 } }, 0.25, YAHOO.util.Easing.easeIn);
notify_display.animate();
// change the rating-value for the form and submit the form
var post_to = rating.ratingform.action;
rating.ratingform.elements[0].value = num;
YAHOO.util.Connect.setForm(rating.ratingform);
var c = YAHOO.util.Connect.asyncRequest('POST', post_to + '?xhr=True', rating.ajax_callback);
}
},
ajax_callback: {
success: function(o) {
// release the form to normal status and change the statustext
rating.submitted = false;
rating.notifytext.innerHTML = 'Rating saved.';
},
failure: function(o) { // we shouldn't ever go down this path.
alert('Error: ' + o.status + " " + o.statusText );
}
}
}
YAHOO.util.Event.addListener(window, 'load', rating.init);
Version history
-
Version 0.1 — 2007-04-06
- First version!













14 comments
great! i think the half-star display for average-rating is pretty cool! Here's another star rating using YUI I used a different approach for the rollover effect though. It'll be great if we can have both (half-star of ave. rating and CSS rollover effect) ;-)
Hello guys, I want to add a star rating to my forum site, is it possible to install this codes and.. can you assist me on how this star rating script works.
Thank you.. I'll pay if this star rating works for my site.
here is my site www.jappinoy.com
Hi! I sow your star rating sistem, and is easy!
I have a blog (http://ignasitrochut.blogspot.com) and I want to put this sistem but I have one question.
The results of rating, is posible to show in one place the best post and add one link show it?
It's possible?
Thank you!
Is the author of this site still alive?
hueueueueuehooooooo
Ignasi: i think your question is not related to this javascript rating system but more to the backend code that you are using.
MasterVision: Yes, I'm still alive, just very busy with Real Work ;) I'm afraid I'm not able to help you with this, sorry. I'm sure there are plenty of eager PHP-developers who can assist you, though. Good luck!
Muuten loistava, MUTTA samalle sivulle ei voi laittaa kuin yhden äänestyksen, sillä jos laittaa monta vain ensimmäinen niistä näkyy graafisena. Käytän tällähetkellä tuota jQuery-versiota, harmi vain kun siinä ei ole tuota mahtavaa ajax-tallennusta... kiitos kuitenkin. Olisi täydellistä jos jaksaisit vaikkapa vaihtaa tuon id:n class-määritelmään, id:tä kun voi käyttää vain kerran samalla sivulla. Tai no mitäpä minä näistä mitään tiedän.
Rolle: firstly, please keep your comments in English! Vast majority of the readers of this blog don't understand Finnish very well :) (For comments in Finnish, feel free to use my contact form)
As for the current limitations of this script, yes, it's currently possible to include only one rating per page. This shouldn't be too hard to fix, though. There are also some other minor tweaks that I'd like to make for version 0.2.
Hopefully I'll get a new version out soon. Subscribe to the RSS-feed to keep informed of the changes!
Sorry about that (posting in finnish). I do like your script so I don't use jQuery-version any longer because I'm not happy without the AJAX-saving. I'm a real amateur in JavaScript so I guess I have to try to modify the script to my needs (to get more ratings per page) while waiting new version. I look forward to see the changes. Keep up the good work!
I use former phpsoft's (today it's borget.info) rating-script for rating-functions and -saving: http://borget.info/?page_id=18 and the page where I'm using the stars is http://rolleweb.net/pelisivu/index.ph...
Great script.
Has anyone implement it with multiple items that need to be rated?
I'm working on such a page and only the first rating item shows up as stars, others show up as regular forms. I think it has something to do with the init function in rating.js and was wondering if anyone has done modifications to make it work.
Thanks,
Dear this is good but can you send me full code for javascripts . really oblige. Please send me on
reachtojack@gmail.com
thanks Jack
Jack, the full code is shown above. All of it. (Also available via the download link provided.)
HI,
Do u have the all js files, because, i downloaded the all linked js files. But its not working.
Hello Friend, Nice job. have you seen fisheye component like the one in macX ? how do u think it could be implemented in YUI ?
cooooooooool!!!!!!!!! I love you!!!!!!!! XD
Comment
Use Markdown for markup. (» Open syntax in new window)