Jquery Lessons: Product stars and how to find rating average

Skip to code | View working example

Image showing product rating information (plus stars), image and Jquery logo.

Image showing product rating information (plus stars), image and Jquery logo.

For those avid followers of my blog posts (all two of you); you may have noticed the content has varied rather a lot over the past few posts. From politics to travel one would be forgiven for wondering what the point is in such a self indulgent rambling from an unknown 20 something. Good point I say. Surely that’s how it must be though. Blogs are by definition a self amplification of one’s thoughts, opinions and work. Until now, I’ve found blogging to be a medium of reflecting my personality as oppose a specific topic. I both apologise and don’t for taking so long to write a “relevant” post.

Onwards with my first instalment of technical delicacies, and I’m sure you’ll agree there’s no better place to start than the front end language which made every Javascript developers life easier – Jquery.

The Challenge

I had to render a rating system only using front end code. Let me clear up what I mean by “render a rating system”. The java developers had provided me with the following variables to play with on a product detail page:

  • Customer review heading
  • Rating number (1-5)
  • Review description

The listed items above were then iterated through for each review. My task was to create the logic to work out an average rating and create a visual indicator (a star!) for the product rating average, and all other customer ratings. Easy you say? Well, it had it’s challenges and I thought it would be handy for others if I jotted them down.

Prerequisites

  • You have an instance of Jquery imported in to the page you’re working with.
  • As described above, the rating systems ‘post a review’ functionality is already in place and the variables are being pulled back in.

The HTML

The idea is you have something like the following from the server side developer:

<!doctype html>
<html>
<head>
<title>Test Title</title>
</head>
<body>
<div class="reviews">
	<h2>Reviews</h2>
	<div class="indivReview">
		<div class="starsContainer">
			<span class="productReviewRating">5</span> <!-- << dynamic value -->
			<span class="starone"></span>
			<span class="startwo"></span>
			<span class="starthree"></span>
			<span class="starfour"></span>
			<span class="starfive"></span>
		</div>
		<h3>Review Heading</h3> <!-- << dynamic value -->
		<p>Review Description</p> <!-- << dynamic value -->
	</div>
	<div class="indivReview">
		<div class="starsContainer">
			<span class="productReviewRating">5</span> <!-- << dynamic value -->
			<span class="starone"></span>
			<span class="startwo"></span>
			<span class="starthree"></span>
			<span class="starfour"></span>
			<span class="starfive"></span>
		</div>
		<h3>Review Heading</h3> <!-- << dynamic value -->
		<p>Review Description</p> <!-- << dynamic value -->
	</div>
	<div class="indivReview">
		<div class="starsContainer">
			<span class="productReviewRating">5</span> <!-- << dynamic value -->
			<span class="starone">
			<span class="startwo"></span>
			<span class="starthree"></span>
			<span class="starfour"></span>
			<span class="starfive"></span>
		</div>
		<h3>Review Heading</h3> <!-- << dynamic value -->
		<p>Review Description</p> <!-- << dynamic value -->
	</div>
</div>
</body>
</html>

The CSS

The following code hides the numerical rating elements from view unless manipulated via Javascript.

<style type="text/css" media="screen">
.starone, .startwo, .starthree, 
.starfour, .starfive {
	display: none;
}
.starone.marker, .startwo.marker, .starthree.marker, 
.starfour.marker, .starfive.marker {
	background: url('http://www.sidavies.co.uk/blog/wp-content/uploads/star.png') top left no-repeat;
	display: block;
	height: 30px;
	width: 30px;
	float: left;
	margin-right: 5px;
}
.productReviewTotalRating, .productReviewRating {
	display: none;
}
</style>

The jQuery

The following code works with the above CSS and HTML snippets. It’s heavily commented and should paint a good picture on what’s going on.

<script type="text/javascript">
$(document).ready(function() {
	// ************************* Average product rating function *************************
	// Define vars
	var numberOfRatings = 0;
	var currentRating = 0;
	var combinedRatingVal = 0;
	var averageRating = 0;
	var cleanCurrentRating = 0;
	var averageMarker = 0;
	if ($(".productReviewRating").length > 0) { // Is there any ratings?
		numberOfRatings = $(".productReviewRating").length; // How many ratings are there?
		$(".indivReview").each( function() {
			currentRating = $(this).find(".productReviewRating").text(); // Grab the current iteration rating value
			cleanCurrentRating = parseInt(currentRating); // Make the ratings a number by using parseInt so we can multiply the rating values
			switch(cleanCurrentRating) { // Add class/es to span.star* based on current iteration rating value 
				case 5:
				$(this).find(".starfive").addClass("marker");
				case 4:
				$(this).find(".starfour").addClass("marker");
				case 3:
				$(this).find(".starthree").addClass("marker");
				case 2:
				$(this).find(".startwo").addClass("marker");
				default:
				$(this).find(".starone").addClass("marker");
				break;
			}
			combinedRatingVal += cleanCurrentRating; // += adds value to current combinedRatingVal on every loop iteration
		});
		averageRating = combinedRatingVal / numberOfRatings; // Our average
		$(".averageRatingVal").find(".productReviewTotalRating").append(averageRating); // Display average value
		averageMarker = $(".averageRatingVal").find(".productReviewTotalRating").text(); // The following carries out same procedure as above for just the newly assigned average rating. This part of the code could be streamlined further.
		averageMarker = parseInt(averageMarker);
		if (averageMarker > 0) {
			switch(averageMarker) {
				case 5:
				$(".averageRatingVal").find(".starfive").addClass("marker");
				case 4:
				$(".averageRatingVal").find(".starfour").addClass("marker");
				case 3:
				$(".averageRatingVal").find(".starthree").addClass("marker");
				case 2:
				$(".averageRatingVal").find(".startwo").addClass("marker");
				default:
				$(".averageRatingVal").find(".starone").addClass("marker");
				break;
			}
		}
	}
	// ************************* End of Average product rating function *************************
});
</script>

I hope the above makes sense. If you have any questions please feel free to leave me a comment and I’ll get back to you. Else, look at a working sample here.

This entry was posted in Code, Jquery, Nerd. Bookmark the permalink.

One Response to Jquery Lessons: Product stars and how to find rating average

  1. Dollie says:

    Many thanks for spending some time to explain the terminlogy to the beginners!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>