Nowadays mainly in every e-commerce website, there is a rating option on the product page. User can rate the product based on its quality, usefulness, etc.
This rating is helpful for the other user who wants to purchase the product.
There are many jQuery plugins are available to add a rating bar on the page.
In this tutorial, I am using the Bootstrap star rating plugin to create rating system in the CodeIgniter 3 project.
Contents
1. Table structure
In this example, I am using two tables –
posts Table – Store post content.
CREATE TABLE `posts` ( `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `title` varchar(100) NOT NULL, `content` text NOT NULL, `link` varchar(255) NOT NULL );
posts_rating Table – Use to store users rating on the posts.
CREATE TABLE `posts_rating` ( `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `userid` int(11) NOT NULL, `postid` int(11) NOT NULL, `rating` int(2) NOT NULL );
2. Configuration
Navigate to application/config/database.php
and define the Database connection.
$db['default'] = array( 'dsn' => '', 'hostname' => 'localhost', 'username' => 'root', // Username 'password' => '', // Password 'database' => 'tutorial', // Database name 'dbdriver' => 'mysqli', 'dbprefix' => '', 'pconnect' => FALSE, 'db_debug' => (ENVIRONMENT !== 'production'), 'cache_on' => FALSE, 'cachedir' => '', 'char_set' => 'utf8', 'dbcollat' => 'utf8_general_ci', 'swap_pre' => '', 'encrypt' => FALSE, 'compress' => FALSE, 'stricton' => FALSE, 'failover' => array(), 'save_queries' => TRUE );
Default controller
Open application/config/routes.php
and edit default_controller
value to Posts
.
$route['default_controller'] = 'Posts';
Load Database
To access the MySQL database require loading database
library.
Open application/config/autoload.php
and add the database
in libraries array()
.
$autoload['libraries'] = array("database");
3. Model
Create a new Main_model.php
file in application/models/
directory.
Here, create 3 methods –
- __construct
- getAllPosts – Fetch all records from
posts
table and also calculate average rating and user rating on a post fromposts_rating
table.
Initialize $posts_arr
with fetched records and return it.
- userRating – Using this method update user rating. Check the user record on the
posts_rating
table. If a record does not exist then insert record otherwise updaterating
field onposts_rating
table.
Calculate the average rating on a post and return it.
Completed Code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); Class Main_model extends CI_Model { public function __construct() { parent::__construct(); } // Fetch records public function getAllPosts($userid) { // Posts $this->db->select('*'); $this->db->from('posts'); $this->db->order_by("id", "asc"); $postsquery = $this->db->get(); $postResult = $postsquery->result_array(); $posts_arr = array(); foreach($postResult as $post){ $id = $post['id']; $title = $post['title']; $link = $post['link']; $content = $post['content']; // User rating $this->db->select('rating'); $this->db->from('posts_rating'); $this->db->where("userid", $userid); $this->db->where("postid", $id); $userRatingquery = $this->db->get(); $userpostResult = $userRatingquery->result_array(); $userRating = 0; if(count($userpostResult)>0){ $userRating = $userpostResult[0]['rating']; } // Average rating $this->db->select('ROUND(AVG(rating),1) as averageRating'); $this->db->from('posts_rating'); $this->db->where("postid", $id); $ratingquery = $this->db->get(); $postResult = $ratingquery->result_array(); $rating = $postResult[0]['averageRating']; if($rating == ''){ $rating = 0; } $posts_arr[] = array("id"=>$id,"title"=>$title,"content"=>$content,"link"=>$link,"rating"=>$userRating,"averagerating"=>$rating); } return $posts_arr; } // Save user rating public function userRating($userid,$postid,$rating){ $this->db->select('*'); $this->db->from('posts_rating'); $this->db->where("postid", $postid); $this->db->where("userid", $userid); $userRatingquery = $this->db->get(); $userRatingResult = $userRatingquery->result_array(); if(count($userRatingResult) > 0){ $postRating_id = $userRatingResult[0]['id']; // Update $value=array('rating'=>$rating); $this->db->where('id',$postRating_id); $this->db->update('posts_rating',$value); }else{ $userRating = array( "postid" => $postid, "userid" => $userid, "rating" => $rating ); $this->db->insert('posts_rating', $userRating); } // Average rating $this->db->select('ROUND(AVG(rating),1) as averageRating'); $this->db->from('posts_rating'); $this->db->where("postid", $postid); $ratingquery = $this->db->get(); $postResult = $ratingquery->result_array(); $rating = $postResult[0]['averageRating']; if($rating == ''){ $rating = 0; } return $rating; } }
4. Controller
Create a new Posts.php
file in application/controllers/
directory.
Here, create 3 methods –
- __construct – Load url helper, session library and Main_model model. Define
userid
SESSION variable and assign 3. - index – Call
Main_model
modelgetAllPosts()
method to fetch all records. Loadpost_view
view and pass$data
. - updateRating – This method is call from jQuery AJAX where rating changed by the user.
Read POST values and pass in userRating()
method to update the user rating.
Return the $averageRating
.
Completed Code
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Posts extends CI_Controller { public function __construct(){ parent::__construct(); $this->load->helper('url'); // Load session $this->load->library('session'); // Load model $this->load->model('Main_model'); // Userid $this->session->set_userdata(array("userid"=>3)); } public function index(){ $data = array(); // Userid $userid = $this->session->userdata('userid'); // Fetch all records $data['posts'] = $this->Main_model->getAllPosts($userid); // Load view $this->load->view('post_view',$data); } // Update rating public function updateRating(){ // userid $userid = $this->session->userdata('userid'); // POST values $postid = $this->input->post('postid'); $rating = $this->input->post('rating'); // Update user rating and get Average rating of a post $averageRating = $this->Main_model->userRating($userid,$postid,$rating); echo $averageRating; exit; } }
5. CSS
Create a assets
directory at project root.
Now create a style.css
file and store in assets
directory.
.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 h2{ 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; }
6. View
Create a new post_view.php
file in application/views/
directory.
Download Bootstrap Start Rating plugin –
- Download the plugin from here.
- Extract the zip file in
assets
directory which created in the previous step.
Layout –
Include CSS and JS of Bootstrap star rating plugin along with bootstrap.min.css
, font-awesome.min.css
, style.css
, and jQuery library in the <head >
section.
Loop on $posts
array and create posts list.
Add rating bar using input element where add class='rating-loading ratingbar' date-min='0' data-max='5'
. Pass $rating
in the value
attribute.
Script –
Initialize rating on $('.ratingbar')
where define showCaption: false, showClear: false, size: 'sm'
.
Also define change
event on $('.ratingbar')
.
Split the id to get the postid and send AJAX POST request to index.php/posts/updateRating
. Pass postid and rating as data
.
On successful callback update the post average rating text by passing response
in $('#averagerating_'+postid).text(response)
.
Completed Code
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Build 5 Star Rating System with jQuery AJAX in CodeIgniter 3</title>
<!-- Bootstrap CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<!-- Font awesome -->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<!-- Bootstrap Star Rating CSS -->
<link href='<?= base_url() ?>assets/bootstrap-star-rating/css/star-rating.min.css' type='text/css' rel='stylesheet'>
<!-- Custom CSS -->
<link href="<?= base_url() ?>assets/style.css" rel="stylesheet">
<!-- jQuery Library -->
<script src='<?= base_url() ?>assets/js/jquery-3.3.1.js' type='text/javascript'></script>
<!-- Bootstrap Star Rating JS -->
<script src='<?= base_url() ?>assets/bootstrap-star-rating/js/star-rating.min.js' type='text/javascript'></script>
</head>
<body>
<div class='content'>
<!-- Post List -->
<?php
foreach($posts as $post){
$id = $post['id'];
$title = $post['title'];
$content = $post['content'];
$link = $post['link'];
$rating = $post['rating']; // User rating on a post
$averagerating = $post['averagerating']; // Average rating
?>
<div class="post">
<h2><a href='<?= $link ?>' class='link' target='_blank'><?= $title; ?></a></h2>
<div class="post-text">
<?= $content; ?>
</div>
<div class="post-action">
<!-- Rating Bar -->
<input id="post_<?= $id ?>" value='<?= $rating ?>' class="rating-loading ratingbar" data-min="0" data-max="5" data-step="1">
<!-- Average Rating -->
<div >Average Rating: <span id='averagerating_<?= $id ?>'><?= $averagerating ?></span></div>
</div>
</div>
<?php
}
?>
</div>
<!-- Script -->
<script type='text/javascript'>
$(document).ready(function(){
// Initialize
$('.ratingbar').rating({
showCaption:false,
showClear: false,
size: 'sm'
});
// Rating change
$('.ratingbar').on('rating:change', function(event, value, caption) {
var id = this.id;
var splitid = id.split('_');
var postid = splitid[1];
$.ajax({
url: '<?= base_url() ?>index.php/employee/updateRating',
type: 'post',
data: {postid: postid, rating: value},
success: function(response){
$('#averagerating_'+postid).text(response);
}
});
});
});
</script>
</body>
</html>
7. Demo
Change the rating. View in a new tab.
7. Conclusion
For the example purpose, I fixed the SESSION userid
variable value to 3. Use your SESSION variable while implementing this on your project.
You need to pass rating value in the input element and initialize rating()
on the selector to create the rating bar.
You can also view this tutorial to know rating system implementation on CodeIgniter 4.
If you found this tutorial helpful then don't forget to share.