The star rating bar allows the user to submit his thoughts on whether the content or product is useful or not. This also gives the administrator a view of how well its item is performing.
It is very common on e-commerce websites.
In this tutorial, I am using the jQuery Bar Rating plugin to display the star ratings on the screen.
Whenever the user changes the rating then send an AJAX request to save the user currently rating status on the MySQL database table with PHP.
Contents
1. Table structure
I am using posts
and post_rating
table in the tutorial example.
posts table
CREATE TABLE `posts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL, `content` text NOT NULL, `link` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
post_rating table
CREATE TABLE IF NOT EXISTS `post_rating` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` int(11) NOT NULL, `postid` int(11) NOT NULL, `rating` int(2) NOT NULL, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
2. Configuration
Create a config.php
for the database connection.
Completed Code
<?php $host = "localhost"; /* Host name */ $user = "root"; /* User */ $password = ""; /* Password */ $dbname = "tutorial"; /* Database name */ $con = mysqli_connect($host, $user, $password,$dbname); // Check connection if (!$con) { die("Connection failed: " . mysqli_connect_error()); }
3. HTML & PHP
Download the jQuery Bar Rating plugin from here.
Load jQuery Bar Rating plugin script with jQuery library and also load a font awesome theme CSS with font awesome CDN file.
I have fixed the userid
to 4
which you can replace with the $_SESSION
variable. Fetch all records from the posts
Table.
Get user rating on the post and average of the post.
Create a layout to show title and content.
Using <select>
element to show the star rating on the screen. Defined data-id
attribute to get element id on the selection in the script.
Set the previously selected rating by calling barrating()
method where pass rating value on the set
.
Completed Code
<?php include "config.php"; ?> <!-- CSS --> <link href="style.css" type="text/css" rel="stylesheet" /> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css"> <link href='jquery-bar-rating-master/dist/themes/fontawesome-stars.css' rel='stylesheet' type='text/css'> <!-- Script --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="jquery-bar-rating-master/dist/jquery.barrating.min.js" type="text/javascript"></script> <div class="content"> <?php $userid = 4; $query = "SELECT * FROM posts"; $result = mysqli_query($con,$query); while($row = mysqli_fetch_array($result)){ $postid = $row['id']; $title = $row['title']; $content = $row['content']; $link = $row['link']; // User rating $query = "SELECT * FROM post_rating WHERE postid=".$postid." and userid=".$userid; $userresult = mysqli_query($con,$query) or die(mysqli_error()); $fetchRating = mysqli_fetch_array($userresult); $rating = $fetchRating['rating']; // get average $query = "SELECT ROUND(AVG(rating),1) as averageRating FROM post_rating WHERE postid=".$postid; $avgresult = mysqli_query($con,$query) or die(mysqli_error()); $fetchAverage = mysqli_fetch_array($avgresult); $averageRating = $fetchAverage['averageRating']; if($averageRating <= 0){ $averageRating = "No rating yet."; } ?> <div class="post"> <h2><a href='<?php echo $link; ?>' class='link' target='_blank'><?php echo $title; ?></a></h2> <div class="post-text"> <?php echo $content; ?> </div> <div class="post-action"> <!-- Rating --> <select class='rating' id='rating_<?php echo $postid; ?>' data-id='rating_<?php echo $postid; ?>'> <option value="1" >1</option> <option value="2" >2</option> <option value="3" >3</option> <option value="4" >4</option> <option value="5" >5</option> </select> <div style='clear: both;'></div> Average Rating : <span id='avgrating_<?php echo $postid; ?>'><?php echo $averageRating; ?></span> <!-- Set rating --> <script type='text/javascript'> $(document).ready(function(){ $('#rating_<?php echo $postid; ?>').barrating('set',<?php echo $rating; ?>); }); </script> </div> </div> <?php } ?> </div>
4. CSS
.content{ border: 0px solid black; border-radius: 3px; padding: 5px; margin: 0 auto; width: 50%; } .post{ border-bottom: 1px solid black; padding: 10px; margin-top: 10px; margin-bottom: 10px; } .post:last-child{ border: 0; } .post h1{ font-weight: normal; font-size: 30px; } .post a.link{ text-decoration: none; color: black; } .post-text{ letter-spacing: 1px; font-size: 15px; font-family: serif; color: gray; text-align: justify; } .post-action{ margin-top: 15px; margin-bottom: 15px; } .like,.unlike{ border: 0; background: none; letter-spacing: 1px; color: lightseagreen; } .like,.unlike:hover{ cursor: pointer; }
5. PHP
Create a rating_ajax.php
file.
Check for a postid
entry by the user in post_rating
Table. If a record exists then update the rating otherwise insert a new record.
Calculate the average rating on the $postid
and return a JSON response.
Completed Code
<?php include "config.php"; $userid = 4; // User id $postid = $_POST['postid']; $rating = $_POST['rating']; // Check entry within table $query = "SELECT COUNT(*) AS cntpost FROM post_rating WHERE postid=".$postid." and userid=".$userid; $result = mysqli_query($con,$query); $fetchdata = mysqli_fetch_array($result); $count = $fetchdata['cntpost']; if($count == 0){ $insertquery = "INSERT INTO post_rating(userid,postid,rating) values(".$userid.",".$postid.",".$rating.")"; mysqli_query($con,$insertquery); }else { $updatequery = "UPDATE post_rating SET rating=" . $rating . " where userid=" . $userid . " and postid=" . $postid; mysqli_query($con,$updatequery); } // get average $query = "SELECT ROUND(AVG(rating),1) as averageRating FROM post_rating WHERE postid=".$postid; $result = mysqli_query($con,$query) or die(mysqli_error()); $fetchAverage = mysqli_fetch_array($result); $averageRating = $fetchAverage['averageRating']; $return_arr = array("averageRating"=>$averageRating); echo json_encode($return_arr);
6. Script
Initialize barrating()
on class='rating'
. Define theme
and onSelect
option.
The onSelect
triggers when a star rating is been changed. Get the element id and split it to get the postid
.
Send an AJAX request where pass postid
and value
variables as data
.
On successful callback update the average value on the <span>
element with the response.
Completed Code
$(function() { $('.rating').barrating({ theme: 'fontawesome-stars', onSelect: function(value, text, event) { // Get element id by data-id attribute var el = this; var el_id = el.$elem.data('id'); // rating was selected by a user if (typeof(event) !== 'undefined') { var split_id = el_id.split("_"); var postid = split_id[1]; // postid // AJAX Request $.ajax({ url: 'rating_ajax.php', type: 'post', data: {postid:postid,rating:value}, dataType: 'json', success: function(data){ // Update average var average = data['averageRating']; $('#avgrating_'+postid).text(average); } }); } } }); });
7. Demo
8. Conclusion
I used the jQuery Bar Rating plugin to implement star rating on the web page. You can use any other plugins for this.
In the demonstration, I have fixed the userid
value which you can update with $_SESSION
variable while implementing on your project.
Great work, thanks. One of the best solutions, I’ve found.
One question: My sites is on a hosted server. I currently only have access to creating ONE database table. Can I somehow merge the two tables in your code? So that I have average vote and number of votes?
Would that work?
Kind regards.
You don’t need another table just to separate average and number of votes. You can easily do it with a single table by the use of the count of votes find the average which I am doing in the tutorial.
Awesome tutorial Yogesh Singh, I will most definitley bookmark your website. This is exactly what I was looking for.
I was wondering if you have any tutorials on how to track the page views of each page/post on my website. I want to display the views for each page/post and not the total views. I can’t seem to find this any tutorials that does this. All of them only display the total views. I would really appreciate it if you could point me in the right direction. Thanks for the awesome work you’re doing.
Hi Gordon,
Currently, I don’t have a tutorial on this.
I will try to publish a tutorial on this soon. Meanwhile, subscribe our newsletter to get notified.
Hello!
Thanks a lot for this great tutorial, the best i have found!
But I’m having a little problem and I really can’t figure out what’s wrong: it won’t take into consideration the vote I make if I click on a star… and doesn’t send the vote to the database.
Otherwise, the average rating from the db is correct.
Hi Besa,
I think there is an error in your AJAX file to check add error: function(data) in $.ajax request and if there is an error then it will display in browser console. According to it debug the code
$.ajax({
url: ‘likeunlike.php’,
type: ‘post’,
data: {postid:postid,rating:value},
dataType: ‘json’,
success: function(data){
// Update average
var average = data[‘averageRating’];
$(‘#avgrating_’+postid).text(average);
},
error: function(data){
console.log(“error : ” + JSON.stringify(data) );
}
});
You can mail me your files at makitweb@gmail.com if the issue is not resolved.
Awesome tutorial, thank you for helping so neatly
Hello, nice tutorial. Just one question, How can I disable ratings? I mean I want to display ratings and do not allow user to submit their ratings from that page.
Add following script at the end of the page –
$(document).ready(function(){
$(‘.br-widget a’).unbind();
});
This script removes all events from the rating element.
Hi… you wouldn’t happen to have a version of this tutorial written for CodeIgniter, would ya? I can’t seem to find a decent CodeIgniter Rating tutorial.
Currently, I have not written the Rating tutorial for CodeIgniter. I will try to publish it soon.
Hi I am getting .barrating is not a function error. do you have any idea about it ?
Hi Danish,
I think jquery.barrating.min.js script is not included in your file that’s why you are viewing this error.
thanks..
You’re welcome.
Thanks you work for me
How to get the star ratings for my site in google search results?
in CodeIgniter…
Hi Yogesh Singh,
First of all what a great tutorial about the 5 star rating system ^^
One of the best and clearest tutos out there imo.
But i have just one question, how can i display the averageRating as stars?
Like now you display it beneath the stars and when the user clicks on a star then the average wil change…
I’d like to display it as stars and not as a number.
And in place of displaying “Average rating :” i’d like to display something like “you voted $yourvote”.
Sorry about my bad English :/
I hope you understand my question?
Kind regards.
I created an example according to your question – Demo. Is this you are trying to implement?
Yes!
That’s what I’m looking for.
Is it also possible to display average rating 3.5 in stars? Like 3 full stars and 1 half star?
The plugin is used in the example currently doesn’t offer half star rating.
if there is no rating against the div the ratings should be blank(stars). Currently it is showing 1 star image i want empty on. can you help on this
can you hep on this
Hi Ashok,
I figure out a way to do this. Need to add an option with 0 value in select element and hide the first anchor element of .br-widget class (.br-widget a:first-child). Here, is the demo link.
Thanks Yogesh 🙂
Hello, if i want to choose 3 stars then choose 0 star. it s stay 1 star can you help me pls 🙂
Hi,
I just downloaded your code and I get this warning message when I’m trying to start the index.php:
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, bool given in C:\xampp\htdocs\rating\index.php on line 61
I’ve already uploaded the sql file to the database. What’s the problem?
Hi Joseph,
I downloaded and checked it is working fine. Have you imported both posts.sql and post_rating.sql file in your MySQL database?
i am not understanding…how to execute
i mean how can i insert my title and content through form
Hello,
Thanks for your tutorial, everything except one thing worked 😉
What is the part of the code which auto-selects the good number of stars when someone has already rated something ? I mean when I refresh my page after rating 4/5, there isn’t 4/5 yellow stars in your example. Maybe I installed something bad.
I have the same error can you help??
Hey Yogesh,
Best one I have found as well. I am running into an issue with the script not adding up the votes and showing anything other than a whole number. It will hold one vote in the system, when the next vote happens it changes to the new whole number, but changes to new number selected, and stays there. The average rating will only show whole numbers. What did I do wrong?
Thanks,
Will
Also I can’t change the $userid from being set by me. the $_sessions change gives me a 500 error:
<?php
$userid = 1; Can't use $userid = $_sessions;
$query = "SELECT * FROM posts";
$result = mysqli_query($con,$query);
And in the Ajax:
include "config.php";
$userid = 1; // User id Can't use $userid = $_sessions;
Hi William,
Have you added session_start() in the config.php file? You need to pass your SESSION variable in which you stored the userid in the $userid variable.
Can you share your code at makitweb@gmail.com so I can check it?
Hey,i need your help in my final year project.i am making a ecommerce website in which i am taking dynamic rating for a product from login..
The rating should save in db and shown in product description..
like how many peoples give rating and show avg rating.I have really no idea how to do it.As my coding is not good,i harshly understanded what you do in your code..an you upload code for my query. I need it..
http://jquery.js
Hello what is the purpose of this lines. i mean where is jquery.js ??
Hi Sakthi,
I stored in the project root. I replaced it with the jQuery CDN.
hey Yogesh Singh,
Thanks for your tutorial, i only have one problem after rating a post when i refresh the page the current selected stars doesn’t remain the same i rated it goes down for one star everytime any help ?
Thanks,
hassan