Top

Follow me and receive all the latest free scripts:

By Email:

Categories
Most Popular Posts

jQuery Star Rating System

jQuery Star Rating System

Published January 05, 2015 by , category jQuery

jQueryStar ratingRating system

A simple and efficient multi-stars rating system that will enhance your website.

Update

I have also written a very precise jQuery/Ajax Star Rating Plugin Tutorial. Please click here to check this new tutorial.

Introduction

Here is a new star rating tutorial using jQuery, MySQL and PHP. This tutorial features:

What is a Media?

I call Media anything you want your visitors rate: photos, images, articles, web pages, videos, or products (for ecommerce websites)…

How do I create my own star image?

Easy! Simply create a 4 states image (with different star colors). This image must include a transparent background, a star showing the non-selected state, a star showing the hover state and a star showing the selected state.

For example in this demo I use a 16x16 pixels star. So my image will be 16 pixels width and 64 pixels high (16x4). 16 pixels high for transparent background, a 16 pixels grey star for the non-selected state, a 16 pixels blue star for the hover state and a 16 pixels yellow star for the selected state.

Imagine you have a 24x24 pixels star; your final image will be 24 pixels width and 96 pixels high (24x4).

What about the cookies?

Each time someone rates a Media, a 1-day cookie is placed on his computer, so he can't vote again for the same Media during the next 24 hours. You may change the time.

How do I install a star bar?

You have a Media on your webpage and you want to allow your visitors to rate it. Just use the code echo starBar(5, 2, 16);. This is a call to a 3 parameters function which are:

  1. The number of stars you want to display (5 stars in this example),
  2. The ID of your Media (2),
  3. The width of your star image (16 in this case).

That's it, the star bar will show up where you want around your Media and people may rate it.

No more talking, here is a demo .

Browsers compatibility

I have tested this plugin on:

Logo Internet Explorer Logo FireFox Logo Chrome Logo Safari
IE 9 Firefox 34.0.5 Chrome Safari 5.1.7

Live demo

Page sample with 4 medias and different star number

3 stars rating system

Rating: 2.50/3 (354 votes)

5 stars rating system

Rating: 4.01/5 (437 votes)

6 stars rating system

Rating: 4.65/6 (308 votes)

10 stars rating system

Rating: 7.45/10 (267 votes)

Examples with different number of stars


20 stars
Rating: 14.57/20 (316 votes)

30 stars
Rating: 20.51/30 (257 votes)

40 stars
Rating: 24.89/40 (205 votes)

50 stars
Rating: 32.30/50 (195 votes)

Files architecture

index.php
db.class.php

ajax

tuto-star-rating.php

jquery

jquery-1.10.1.min.js

js

tuto-star-rating.js

design

Database structure sample

id is an auto-increment field. media (an integer) is your Media ID. rate (an integer) is the visitor's rate (a number from 1 to 5 for a 5 star rating system).

CREATE TABLE IF NOT EXISTS `tc_tuto_rating` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `media` int(6) NOT NULL,
  `rate` int(3) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;

HTML/PHP code

This is the index.php page (the complete structure). I include the CSS style lines (which may be placed in a style.css file) and the function starBar which can also be placed in a separate file.

<?PHP
include('db.class.php');
$bdd = new db();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
	<title>Star Rating System</title>
	
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">

	<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" type="text/css">
	
	<script type="text/javascript" src="jquery/jquery-1.10.1.min.js"></script>
    
	<style>
		.no_star { display: inline-block; background: url("design/star.png") no-repeat; width: 16px; height: 16px }
		.star { display: inline-block; background: url("design/star.png") no-repeat; background-position: 0 -16px; width: 16px; height: 16px }
		.star_hover { display: inline-block; background: url("design/star.png") no-repeat; background-position: 0 -32px; width: 16px; height: 16px }
		.star_selected { display: inline-block; background: url("design/star.png") no-repeat; background-position: 0 -48px; width: 16px; height: 16px }
	</style>
</head>

<body>

<div class="container">
	<div class="row">
		
		<div class="col-md-12">
			<br /><br />
			<?php
			function starBar($numStar, $mediaId, $starWidth) { // function with arguments: number of stars, media ID, width of the star image
				global $bdd;
				
				$cookie_name = 'tcRatingSystem'.$mediaId; // Set up the cookie name
				
				// We get the rate average and number of rate from the database
				$query = $bdd->getOne('SELECT round(avg(rate), 2) AS average, count(rate) AS nbrRate FROM tc_tuto_rating WHERE media='.$mediaId.'');
				$avgCeil = round($query['average'], 0); // round above or below to show how many selected stars we display
				
				$getJSON = array('numStar' => $numStar, 'mediaId' => $mediaId); // We create a JSON with the number of stars and the media ID
				$getJSON = json_encode($getJSON);
				
				// We create the DIV block with selected stars and unselected stars depending of the rate
				$starBar = '<div id="'.$mediaId.'">';
				$starBar .= '<div class="';
				if( !isset($_COOKIE[$cookie_name]) ) $starBar .= 'star_bar';
				$starBar .= '" rel='.$getJSON.' style="width:'.($numStar*$starWidth).'px">';
				
				for ($i=1; $i<=$numStar; $i++) {
					$starBar .= '<div class="';
					if ($i <= $avgCeil) $starBar .= 'star_selected'; else $starBar .= 'star';
					$starBar .= '"></div>';
				}
				$starBar .= '</div>';
				$starBar .= '<div class="resultMedia'.$mediaId.'" style="font-size: small; color: grey">'; // We show the rate score and number of rates
				if ($query['nbrRate'] == 0) $starBar .= 'Not rated yet';
				else $starBar .= 'Rating: ' . $query['average'] . '/' . $numStar . ' (' . $query['nbrRate'] . ' votes)';
				$starBar .= '</div>';
				$starBar .= '<div class="box'.$mediaId.'"></div>'; // Return the text "Thank you for rating" when someone rate
				$starBar .= '</div>';
				
				return $starBar;
			}
			
			echo starBar(5, 30, 16); // We create star bar
			echo starBar(5, 31, 16);
			echo starBar(6, 27, 16);			
			echo starBar(20, 28, 16);			
			echo starBar(100, 29, 16);			
			?>
		</div>
		
	</div>
</div>

<script type="text/javascript" src="js/tuto-star-rating.js"></script>

</body>
</html>

PHP code

It's the ajax/tuto-star-rating.php file, called by the Ajax function for data treatment.

<?php
include('../db.class.php'); // Connection to database
$bdd = new db();

if($_POST) {
	$mediaId = $_POST['mediaId']; // Media ID
	$rate = $_POST['rate']; // Your rate
	
	$expire = 24*3600; // 1 day
	setcookie('tcRatingSystem'.$mediaId, 'voted', time() + $expire, '/'); // Place a cookie
	
	$query = $bdd->execute('INSERT INTO tc_tuto_rating (media, rate) VALUES ('.$mediaId.', "'.$rate.'")'); // We insert the new rate
	
	// We calculate the new average and new number of rate
	$result = $bdd->getOne('SELECT round(avg(rate), 2) AS average, count(rate) AS nbrRate FROM tc_tuto_rating WHERE media='.$mediaId.'');
	
	$avgCeil = round($result['average'], 0); // Round the average
	
	// Send JSON back with the new average, the number of rate and rounded average
	$dataBack = array('avg' => $result['average'], 'nbrRate' => $result['nbrRate'], 'avgCeil' => $avgCeil);
	$dataBack = json_encode($dataBack);
	
	echo $dataBack;
}
?>

jQuery code

It's the js/tuto-star-rating.js file.

function rateMedia(mediaId, rate, numStar) {
	$('.box' + mediaId).html('<img src="design/loader-small.gif" alt="" />'); // Display a processing icon
	var data = {mediaId: mediaId, rate: rate}; // Create JSON which will be send via Ajax
	
	$.ajax({ // JQuery Ajax
		type: 'POST',
		url: 'ajax/tuto-star-rating.php', // URL to the PHP file which will insert new value in the database
		data: data, // We send the data string
		dataType: 'json',
		timeout: 3000,
		success: function(data) {
			$('.box' + mediaId).html('<div style="font-size: small; color: green">Thank you for rating</div>'); // Return "Thank you for rating"
			// We update the rating score and number of rates
			$('.resultMedia' + mediaId).html('<div style="font-size: small; color: grey">Rating: ' + data.avg + '/' + numStar + ' (' + data.nbrRate + ' votes)</div>');
			
			// We recalculate the star bar with new selected stars and unselected stars
			var ratingBar = '';
			for ( var i = 1; i <= numStar; i++ ) {
				ratingBar += '<div class="';
				if (i <= data.avgCeil) ratingBar += 'star_selected'; else ratingBar += 'star';
				ratingBar += '"></div>';
			}
			
			$('#' + mediaId + ' .star_bar').html(ratingBar).off('mouseenter');
		},
		error: function() {
			$('#box').text('Problem');
		}
	});
}

$(function () {
	$('.star_bar').on('mouseenter', function overBar(event) { // Mouse enter the star bar
		var relData = $.parseJSON($(this).attr('rel')); // Get JSON values: number of stars and media ID
		
		$(this).css('cursor','pointer');
		
		// We create a new star bar OVER the previous one with transparent stars
		var newStarBar = '';
		for ( var i = 1; i <= relData.numStar; i++ ) {
			newStarBar += '<div class="no_star" id="' + i + '" title="' + i + '/' + relData.numStar + '" onclick="rateMedia(' + relData.mediaId + ', ' + i + ', ' + relData.numStar + '); return false;"></div>';
		}
		$(this).css('position', 'relative').append('<div id="over' + relData.mediaId + '" style="position:absolute; top:0; left:0;">' + newStarBar + '</div>');
		
		// When we move the mouse over the new transparent star bar they become blue
		$('#over' + relData.mediaId + ' > div').mouseover(function() {
			var myRate = $(this).attr('id');
			for ( var i = 1; i <= relData.numStar; i++ ) {
				if (i <= myRate) $('#over' + relData.mediaId + ' #' + i).attr('class', 'star_hover');
				else $('#over' + relData.mediaId + ' #' + i).attr('class', 'no_star');
			}
		});
	});
	
	// Mouse leaves the star bar, we remove the rating bar
	$('.star_bar').on('mouseleave', function overBar(event) {
		var relData = $.parseJSON($(this).attr('rel'));
		$('#over' + relData.mediaId).remove();
	});
});

Conclusion

If you look for voting system, you may be interested by this Thumbs up & Thumbs down system or this Facebook Like System.

If you have questions or if you need help, please comment below. For special requests please contact me.

About Simon Laroche
Simon Laroche on Google+
Simon Laroche on Twitter
Simon Laroche on Facebook
Simon Laroche on Pinterest
Simon Laroche on LinkedIn
: I am a Coder, Designer, Webmaster and Expert SEO Consulting, I'm also a wise traveller and an avid amateur photographer. I created the website TipoCode and many others such as Landolia: a World of Photos...

If you need help about this script, please leave a comment below. I reply as much as I can depending of my time, you may also get help from others.
I also offer a paid support, if you are in the need to adapt or create a script...

Leave a comment

Comments (1 comment)

Murat Posted on July 16, 2016
Hello. thank you for this article. How can we integrate this product to laravel ? Thank you in advance.