The star rating system on the website makes it easy for users to provide feedback and help others make their choices. It provides businesses with feedback on how customers like their products. Star ratings also help build trust in a website and its products.
All major e-commerce sites use ratings to let buyers know the quality they can expect from products.
In this tutorial, I'll show you how to build your own five-star rating system.
The first step in the process of building a star rating system is writing the markup, which depends on the elements we want to display on the page.
We definitely want to include the name of the movie in our ratings widget. We also need to display five stars within the widget that users can click to vote. After users vote, we will also display voting data to them.
The following HTML achieves all this:
<div class="rating-wrapper" data-id="raiders"> <h2>Raiders of the Lost Ark</h2> <div class="star-wrapper"> <i class="fa-regular fa-star"></i> <i class="fa-regular fa-star"></i> <i class="fa-regular fa-star"></i> <i class="fa-regular fa-star"></i> <i class="fa-regular fa-star"></i> </div> <p class="v-data">Voting Data</p> </div>
I'm using the Font Awesome library to add the stars. By default, we want the stars to have a black stroke and no fill. fa-regular
Classes do this for us.
We also want the star's color to change to light yellow when the user hovers over it and to orange when the user clicks on the star to indicate that their rating has been is recorded. The following CSS does it all for us:
div.rating-wrapper { display: flex; align-items: first baseline; flex-direction: column; margin: 5rem; font-size: 1.5rem; } div.star-wrapper { font-size: 2rem; } div.star-wrapper i { cursor: pointer; } div.star-wrapper i.yellow { color: #FDD835; } div.star-wrapper i.vote-recorded { color: #F57C00; } p.v-data { background: #ccc; padding: 0.5rem; }
We will now use some jQuery to respond to user events. There are two events we want to track on our star.
Let's start with the mouseover
event, which will turn our hovering star and all of its previous brothers yellow. However, this only happens if the user has not clicked on the star to register to vote. We'll do this by manipulating the Font Awesome star icon's class.
This is the code we need:
$("div.star-wrapper i").on("mouseover", function () { if ($(this).siblings("i.vote-recorded").length == 0) { $(this).prevAll().addBack().addClass("fa-solid yellow").removeClass("fa-regular"); $(this).nextAll().removeClass("fa-solid yellow").addClass("fa-regular"); } });
We use a if
statement to check if our currently hovering star has any siblings, and attach the vote-recorded
class. The presence of any such element indicates that the vote was recorded. In this case we don't do any class manipulation.
However, if the vote has not yet been recorded, we will get the current element and all siblings before it and add the fa-solid
and yellow
classes to them. We also remove these classes from all sibling elements that follow the current element.
Now, we will write the jQuery code that handles the click
event. Whenever a user clicks on the fourth star, we know they want to rate the movie four stars. So we record the number of previous brothers and add one to get rating
. We also log the movie_id
to add the rating to the correct movie.
$("div.star-wrapper i").on("click", function () { let rating = $(this).prevAll().length + 1; let movie_id = $(this).closest("div.rating-wrapper").data("id"); if ($(this).siblings("i.vote-recorded").length == 0) { $(this).prevAll().addBack().addClass("vote-recorded"); $.post("update_ratings.php", { movie_id: movie_id, user_rating: rating }).done( function (data) { parent_div.find("p.v-data").text(data); } ); } });
Let's double check if a vote has been recorded for that particular movie. If the vote has not been recorded yet, we add the vote-recorded
class to the currently clicked element and all its previous siblings.
We also use the jQuery post()
method to send voting data to the backend via a POST request. The first parameter is the URL of the PHP script that will handle our request, while the second parameter is the data we want to process.
We also provide callbacks in done()
to further process the data sent to us from the server after our request has been successfully processed.
The following CodePen demo shows what the front-end of our rating system would look like:
We will use a MySQL database to store our voting records on the backend. You can use any application you like to manage the database. I'm using phpMyAdmin. The first step here is to create a database, which I will name rating_test
. Now, we will create a table named movie_ ratings
in the database. Run the following SQL query on the database to create the table:
CREATE TABLE `movie_ratings`( `id` INT(11) NOT NULL AUTO_INCREMENT, `movie_id` VARCHAR(128) NOT NULL DEFAULT '', `average_rating` DOUBLE NOT NULL DEFAULT 0, `total_votes` DOUBLE NOT NULL DEFAULT 0, PRIMARY KEY(`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
Executing the above statement will create a table named movie_ ratings
, which contains four different columns.
The first one is the auto-incrementing id
, which serves as the primary key for every record we add to the table. The second is movie_id
, which will identify a movie and can contain up to 128 characters. The third one is average_ rating
to store the average of all votes cast so far. The fourth, total_votes
, is used to track the total number of votes cast.
Let’s review the first parameter of the post()
method in the previous section. You will see the string update_atings.php, this is the file we need to create now. This file will contain the PHP code that updates and records the movie's rating.
$movie_id = $_POST['movie_id']; $user_rating = $_POST['user_rating']; $mysqli = new mysqli('localhost', 'root', '', 'rating_test'); if ($mysqli->connect_errno) { die("Error while connecting: " . $mysqli->connect_error); }
我们首先使用 $_POST
获取 POST 数据,然后创建一个新的 mysqli
对象来建立与数据库的连接。然后我们检查 connect_errno
的值,看看我们的数据库连接调用期间是否出现错误。
$rating_query = $mysqli->query("SELECT * from `movie_ratings` WHERE `movie_id` = '$movie_id'"); $rating_query_rows = mysqli_num_rows($rating_query); if($rating_query_rows == 0) { $mysqli->query("INSERT INTO `movie_ratings` (`movie_id`, `average_rating`, `total_votes`) VALUES ('$movie_id', $user_rating, 1)"); echo "Average Rating: $user_rating Total Votes: 1"; } else { $rating_data = $rating_query->fetch_array(MYSQLI_ASSOC); $total_votes = $rating_data['total_votes']; $average_rating = $rating_data['average_rating']; $rating_sum = $average_rating*$total_votes + $user_rating; $total_votes += 1; $new_average_rating = round($rating_sum/($total_votes), 2); $mysqli->query("UPDATE `movie_ratings` SET `average_rating` = $new_average_rating, `total_votes` = $total_votes WHERE `movie_id` = '$movie_id'"); echo "Average Rating: $new_average_rating Total Votes: $total_votes"; }
建立连接后,我们运行第一个查询来查看是否已存在要更新其评分的电影的行。
如果没有这样的电影,我们运行另一个查询以将电影插入表中。由于这是该电影的第一次投票,因此我们将总票数设置为 1。
但是,如果表中已经有一行包含我们传递的 movie_id
,我们将从该行获取电影的总票数和当前平均评分。之后,我们计算新的评分并相应更新数据库。
最后,我们回显平均评分和总票数的新值以将其显示给用户。
为了简单起见,这不是 100% 完整的解决方案。为了扩展这个项目,我们应该存储一个 cookie 以确保人们只投票一次,甚至记录 IP 地址。然而,这是一个很好的开始,并且非常适合跟踪对您网站上的博客文章、评论和图像等项目的投票。
The above is the detailed content of Build a 5-star rating system using jQuery, AJAX, and PHP. For more information, please follow other related articles on the PHP Chinese website!