Develop a feedback form with Star Ratings in PHP, MySQL and jQuery

Star Rating is normally used in a feedback form. Users can select a rating for a particular service or product and submit the form. You can develop this form and save the feedback in the database using jQuery with PHP and MySQL. In this topic, we will show how to select a star rating (0-5) for various categories of services and submit the feedback form. We will use the below star rating description for each rating.

0 - No Rating, 1- One Star, 2 - Two Star, 3 - Three Star, 4 - Four Star, 5 - Five Star.

display star rating in phpFolders and Files

star rating feedback form

We are using a folder called 'feedback' under 'xampp/htdocs'.

Folder 'cfg' - we have dbconnect.php in this folder. This php program is used to connect to MySQL database
Folder 'css' - We have a custom stylesheet in this folder
Folder 'js' - In this folder we have our custom JavaScript file
index.php is the main program that presents the feedback form.
process_feedback.php is the php program to process the form and update the database after the form is submitted.

dynamic star rating javascript

In the above form, user can select a star rating for each of the services. When the user brings the mouse over the stars, rating caption changes on the right side and on clicking any star, rating will be selected.

Create the tables in MySQL database

We will have two tables FEEDBACK_ITEM and FEEDBACK_FORM in MySQL database. The first one is to store a list of services for which feedback is to be taken and the other one is to store user ratings for each service. The table structures are given below:

Table1 : FEEDBACK_ITEM

This table stores all items for which feedback is to be taken from the user.

Star Rating in PHP and jquery

Table has 2 columns.

  1. id - primary key and auto incremented
  2. descr - Description of the item

feedback_item.sql


CREATE TABLE `feedback_item` (
  `id` int(11) NOT NULL,
  `descr` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `feedback_item` (`id`, `descr`) VALUES
(1, 'Room Service'),
(2, 'Reception'),
(3, 'Food'),
(4, 'Cleainess'),
(5, 'Check-in'),
(6, 'Check-out'),
(7, 'Over All Service');

ALTER TABLE `feedback_item`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `feedback_item`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;

Table2 : FEEDBACK_FORM

This table stores the actual feedback for each item given by the users. Customers of the hotel will use this feedback form.

feedback form in php using star rating

Table has 5 columns.

  1. id - primary key and auto incremented
  2. userid - Userid of the user who is participating in feedback. In our example, we are not storing userid as the login option is not included in this example. If you implement login then you can store logged in userid in this table. I have used the client IP address as userid here.
  3. feedback_item_id - id of the feedback item. This id comes from the feedback_item table
  4. rating - Rating given by the user, it is stored as integer 0 to 5.
  5. date - Date of feedback given by the user

feedback_form.sql


CREATE TABLE `feedback_form` (
  `id` int(11) NOT NULL,
  `userid` varchar(200) NOT NULL,
  `feedback_item_id` int(11) NOT NULL,
  `rating` tinyint(4) NOT NULL,
  `date` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `feedback_form`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `feedback_form`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

Connect to MySQL database (dbconnect.php)

Use the below script to connect to the database. We will keep this file under "cfg" folder and include it in other programs.

dbconnect.php


<?php
  $server="localhost";
  $userid="root";
  $pwd="";
  $dbname="test";
  $conn = mysqli_connect($server, $userid, $pwd, $dbname);
//Check connection
if (!$conn) 
  	die("Connection Error: " . mysqli_connect_error());

We will use mysqli_connect() function with the below four parameters.

These four parameters are:

  1. server - it is localhost
  2. userid - we are using root user
  3. password - no password for user root
  4. database name - test in our case.
If connection is successful, it will return true, otherwise, it will return false. You can also read the topic How to connect to MySQL database in PHP using MySQLi and PDO.

Create the Feedback Form (index.php)

feedback form in php jquery and mysql using star rating

It selects all the feedback items from the feedback_item table and in a loop, it displays feedback names with ids (hidden) in an html table. For each feedback, it displays a minus symbol (-) for No-Rating and star symbols for star ratings. Users can not submit the form without selecting a rating for all services. See the code for index.php below:

index.php


<!DOCTYPE html>
<html lang="en">
<head>
  <title>Feedback Form</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link  rel="stylesheet" href="css/style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="js/feedback.js"></script>
</head>
<body>
 <div class="container">
		<h2>Feedback Form</h2>
		<p>Please rate your experience against each item, if you do not want to rate any service, then select <span class="badge badge1"><span class="glyphicon glyphicon-minus"></span></span><span class="label label-danger">No Rating</span></p>
		<!-- Show feedback items in a table -->
		<div class="col-md-12">
			<form class="frm" action="process_feedback.php" method="post" onsubmit="return checkForm()">
				<table class="tbl-feedback">
					<thead>
						<tr><th>Service</th><th>Rating</th><th></th></tr>
					</thead>
					<tbody>
						<?php
						include "cfg/dbconnect.php";
						$sql = "select * from feedback_item order by id";
						$result = mysqli_query($conn,$sql);
						if(!empty($result)) {
							foreach ($result as $item) { ?>
								<tr>
									<td  style="width:400px;"><div class="service"><?=$item["descr"]; ?></div></td>
									<td>
										<div class="show-star" id="item-<?=$item["id"];?>">
											<input type="hidden" name="feedback_item_id[]" value="<?php echo $item['id']?>">
											
											<input type="hidden" class="form-control rating" name="rating[]" id="rating<?=$item['id'];?>" value=""/>
											<ul>
									 			<li class="badge" onMouseover="showStar(this,<?=$item['id'];?>);" onMouseout="removeStar(<?=$item['id'];?>);" onClick="selectStar(this,<?=$item['id'];?>);" title="Clear"><span class="glyphicon glyphicon-minus"></span>
									 			</li> 
												 <?php
												  for($i=1;$i<=5;$i++) {
													  ?>
													  	<li class="star" onMouseover="showStar(this,<?=$item['id'];?>);" onMouseout="removeStar(<?=$item['id'];?>);" onClick="selectStar(this,<?=$item['id'];?>)">★
													  	</li> 
												  <?php }  ?> 
											</ul>
										</div>
									</td>
									<td>
										<div class="show-star">
											<span id ="showCaption<?=$item['id'];?>"></span>
					  				</div>
						  		</td>
								</tr>
							<?php		
							}
						}
						?>
					</tbody>
			  </table>
		  	<div class="col-md-12 form-group btn-submit">
			 		<input type="submit" class="btn btn-primary" name="submit" value="Submit"/>
		  	</div>
			</form>
		</div>
	</div>
</body>
</html>

JavaScript function checkForm() is to validate the form, i.e., if the user has missed feedback for any services. This function is written in feedback.js file in the 'js' folder.

Note that we are using dynamic id in line 33, 34 and 36 to identify each item separately. These ids will be used in jQuery.

Highlighting and selecting of the stars are done using three events onMouseOver, onMouseOut and onClick.

For each event, a JavaScript function is called.
onMouseOver - showStar() function highlights the stars and corresponding text appears on the right side.
onMouseOut - removeStar() function removes a highlight and corresponding text disappears.
onClick - selectStar() function selects a particular star and displays the corresponding text on the right side. It also assigns a value (0-5) to a hidden rating field. Note that it works the same way as both Not-Rated symbol and Star symbols.

Write JavaScript/jQuery (feedback.js)

There are two arrays defined at the beginning, one has all captions like "No Rating", "One Star", "Two Star" up to "Five Star" and the other array has all labels like label-default, label-danger, etc.


// 2 arrays are defined to store caption along with color to be displayed when 
// respective star rating and no rating is selecetd
var captionLabelArr =["label label-danger","label label-danger","label label-warning","label label-info","label label-primary","label label-success"];
var captionArr =["No Rating","One Star","Two Star","Three Star","Four Star","Five Star"];

Function removeStar()


function removeStar(id) {
// removeStar() function removes highlight and then show the existing selected star
// also removes highlight for no rating sysmbol
	$("#item-"+id+" li").removeClass("highlight");
	$("#showCaption"+id).removeClass();
	$("#showCaption"+id).html("");
	var selectedVal = $('#rating'+id).val();
	captionClass = captionLabelArr[selectedVal];
	caption = captionArr[selectedVal];
	$("#showCaption"+id).addClass(captionClass);
	$("#showCaption"+id).html(caption);
}

removeStar() function removes all highlighted stars and no-rating symbols. It also removes the corresponding caption. Once all are removed, it checks if any rating is selected and accordingly displays the caption.

Function showStar()


function showStar(obj,id) {
// showStar() function hightlights star on mouseover
// it highlights no rating and star sysmbols separately
	removeStar(id);		// first remove existing highlight
	$("#item-"+id+" li").each(function(index) {
		var captionClass = caption = "";
		if ($("#item-"+id+" li").index(obj) == 0){ 			// for no rating
			if(index == $("#item-"+id+" li").index(obj)) {  
				captionClass = captionLabelArr[0];
				caption = captionArr[0];
				$("#showCaption"+id).removeClass();
				$("#showCaption"+id).addClass(captionClass);
				$("#showCaption"+id).html(caption);
				return false;
			}
		}
		else { 			// for star
			if (index > 0) {
				$(this).addClass("highlight");
				if(index == $("#item-"+id+" li").index(obj)) {
					captionClass = captionLabelArr[index];
					caption = captionArr[index];
					$("#showCaption"+id).removeClass();
					$("#showCaption"+id).addClass(captionClass);
					$("#showCaption"+id).html(caption);
					return false;	
				}
			}
		}
	});
}

This function is called on onMouseover event of the star symbol or no-rating symbol. It is called with two parameters; one is the object (the symbol) and other is the id of the item (service name). This function only highlights the corresponding star or no-rating symbol.

Function selectStar()


function selectStar(obj,id) {
// selectStar() function is called onclick event on star or no rating sysmbol
// displays all stars highlighted rating of which less than or equal to the selected rating
// it also highlights and selects if "No Rating" sysmbol is clicked 
	 $("#item-"+id+" li").removeClass("selected");
	 $("#item-"+id+" .badge").removeClass("sel-not-rated");
	$("#item-"+id+" li").each(function(index) {
		var captionClass = caption = "";
		if($("#item-"+id+" li").index(obj) == 0) {  // for no rating
			if(index == $("#item-"+id+" li").index(obj)) {  
				$("#item-"+id+" .badge").addClass("sel-not-rated");
				$("#rating"+id).val("0");
				return false;
			}
		}
		else { 							
			if (index > 0) { 	// for star
				$(this).addClass("selected");
				if(index == $("#item-"+id+" li").index(obj)) {
					$("#rating"+id).val(index);
					return false;	
				}
			}
		}
	});
}

selectStar() function works the same way as showStar(). Instead of just highlighting, it will select the rating and highlight the stars. It is called on the onClick event of the star symbol or No-Rating symbol.

Function checkForm()


function checkForm(){
// called when form is submitted
// it checks if rating is given for all items, if not, do not allow to submit
	var ratingClass = document.getElementsByClassName("rating");
	for (var i=0;i<ratingClass.length;i++){
		if (ratingClass[i].value == ""){
			alert("Please complete all items");
			return false;
		}
	}
}

This function is called on the onSubmit event of the form.

Process form data (process_feedback.php)

Now we write PHP code for form submission. When the form is submitted, we need to process the values submitted to insert into the database tables and show the appropriate message.

Check the code below:

process_feedback.php


<?php
include "cfg/dbconnect.php";
if (isset($_POST['submit'])){
	mysqli_autocommit($conn, false);
	$flag = true;
	$feedback_item_id = $_POST['feedback_item_id'];
	$userid = $_SERVER['REMOTE_ADDR']; 
	$rating = $_POST['rating'];
	$date = date('Y-m-d');
	if(isset($_COOKIE["feedback"])){  // check if cookie exists
		echo '<h2 style="text-align:center;">You have already submited your feedback</h2>';
	}
	else { // if not exists then insert and add cookie
			for ($i=0;$i<count($feedback_item_id);$i++){
				$sql = "insert into feedback_form(userid,feedback_item_id,rating,date) values('$userid','$feedback_item_id[$i]','$rating[$i]','$date')";
				$result = mysqli_query($conn,$sql);
				if (!$result) {
					$flag = false;
					break;
					}
			}
		if ($flag) { 	// successful, commit and create cookie
			mysqli_commit($conn); 
			setcookie ("feedback","submitted",time()+ 3600*24*180); // 6 months valid
	      	echo '<h2 style="color:#0b7f0b;text-align:center;">Thank You for Submitting your Feedback</h2>';
	    }
	    else {  // if error occurs rollback all feedback items and do not create cookie
	    		mysqli_rollback($conn);
	      		echo '<h2 style="color:#f44336;text-align:center;">Error Occurred:Could not Submit Feedback, please try later</h2>';
	    		}
	    }	
}
?>

Here we use commit and rollback as rows will be inserted one after the other for each feedback item. For the user id, we are using a remote client address. You can use login user id also if you implement login.

We are almost done; we just need to add styles.

Add CSS (style.css)

Let us add the below styles.

style.css


* {
	box-sizing: border-box;
}
body{
	font-size: 18px;
}
.container{
	padding-bottom: 40px;
}
h2,h3 {
	text-align: center;
}
.frm {
	width:70%;
	margin:auto;
}
.label{
	font-size: 15px;
	/*width:100px;*/
}
textarea{
	resize:none;
	height:100px!important;
}
.btn-submit{
text-align:center;
margin-top: 20px;
}
.rating{
	margin-bottom: 0;
}
.sel-not-rated{
	color:#fff;
	background: #b03838;
}
.badge{
	padding:3px;
	margin-top: -10px;
	margin-right: 10px;
}
.badge1{
	padding:3px;
	margin-top: 0;
	margin-right: 10px;
}
.tbl-feedback {
	width: 100%;
	border-spacing: initial;
	line-height:26px;
	margin: auto;
	margin-top:20px;
	padding-bottom: 20px;
}
.tbl-feedback th {
	background-color: #2982b6ed;
	color:#fff;
	padding: 4px;
}
.tbl-feedback td {
	border-bottom: #e9dcdc 1px solid;
	padding: 4px;

}
.tbl-feedback td div.service{
	text-decoration: none;
	color:#4685bc;
	font-weight:bold;
}
.tbl-feedback ul{
	margin:0!important;
	padding:0!important;
}
.tbl-feedback .star{
	cursor:pointer;
	display: inline-block;
	text-shadow: 0 0 1px #666666;
	color: #aaa;
	font-size:28px;
}
.tbl-feedback .selected {
	color:#F4B30A;
	text-shadow: 0 0 1px #F48F0A;
}
.tbl-feedback .highlight {
	color:#F4B30A;
	text-shadow: 0 0 1px #F48F0A;
}
p{
	text-align: center;
}
a{
  text-decoration: none;
  color: #000;
}

You can see, various classes that were dynamically added/removed using jQuery are added here. Keep this style.css file in the css folder.

Star Rating in PHP and jqueryTest the Application

In your XAMPP control panel, Apache and MySQL services should be running. Run localhost/feedback in the browser.

Test if the rating and captions are showing correctly when you roll over the mouse on any star. Then give ratings and submit the form. Now run index.php again and try to submit the ratings to check if the cookie is correctly being written.

PHP Star Rating System with JavaScript jquery and mysql

Create Review Rating Page in PHP with jqueryNote

To prevent multiple submission of the same feedback, I have used cookie here. Even though, one can remove cookies and submit again. However, you can always use user login to submit the feedback, so that one user can submit the form once only.

Star Rating System Using PHP and JavaScriptDownload Source Code

You can download the full source code by clicking on the Download button below. You can directly use the code or modify it as per your requirements.

Build PHP MySQL 5 Star Rating System using jQueryConclusion

In this topic, I have explained how you can use a form with the star ratings to submit the feedback. I have given an example of the hotel services; it can be a rating for a product or someone's performance. You can change it to meet your requirements and use it for any similar application. I hope it will be useful to you.