Do you have an interesting product, article, or service that you offer?
Adding a customer rating system can help you determine if customers actually love your articles, services, or products and you can use their negative reviews as a motive to improve your service.
Today, I will show you how to create a simple star rating using HTML, CSS, and JavaScript, and by the end of this article, you will be able to link your backend logic to save the rating.
LET'S BEGIN
I will start by creating the HTML tags, and declaring some rules in CSS so that we will focus on the JavaScript code.
Let's create a star rating container that will contain 5 stars. We will also set an attribute and a class that will help us identify each of the stars.
<p class="star-rating">
<i class="my-star star-1" data-star="1"></i>
<i class="my-star star-2" data-star="2"></i>
<i class="my-star star-3" data-star="3"></i>
<i class="my-star star-4" data-star="4"></i>
<i class="my-star star-5" data-star="5"></i>
</p>
At the moment you will only see a blank page. Let us declare some CSS rules that will spice up our star rating.
/*set the default color of the stars*/
.star-rating{
color: #bebebe;
font-size:2em;
}
/*create the star*/
.my-star::before{
content:"\002605";
}
/*remove the default style (italic) of the star*/
.my-star{
font-style: unset !important;
}
/*set active star color*/
.is-active{
color:#fb8900;
}
/*set color on hover*/
.my-star:not(.is-active):hover{
color: #fb8900;
}
Let us preview our code.
Currently, we have empty stars and no action will execute when you click on any of the stars, because we have not added our javascript code. Let's do so now.
JavaScript Code
We will query all elements with the my-star class, loop through each of them, and attach a click event that will output the value of data-star.
This value will be the star element selected by the user.
document.addEventListener('DOMContentLoaded', function(){
(function(){
let sr = document.querySelectorAll('.my-star');
let i = 0;
//loop through stars
while (i < sr.length){
//attach click event
sr[i].addEventListener('click', function(){
//current star
let cs = parseInt(this.getAttribute("data-star"));
//output current clicked star value
document.querySelector('#output').value = cs;
})//end of click event
i++;
}//end of while loop
})();//end of function
})
Before we reload our page, let's create an input element that will store the value of the star clicked by a user.
<input type="number" readonly id="output">
So when you reload and click on a star, you will see the value of the star you clicked on. This was made possible because we attached an attribute data-star to the star elements that will enable us to identify each of the stars.
Looking at the code, I can say that we have completed our little project, but let's add one more thing.
One More Thing
Normally if you should click on 2 stars and above, the preceding stars will be active (ie they should make use of the is-active class), and the succeeding stars will bear their default color just like the image below.
We can achieve this by checking the current value of the star, then creating 2 loops where one of the loops will set the is-active class on the preceding stars and unset the is-active class on the succeeding stars.
The first loop (included)
document.addEventListener('DOMContentLoaded', function(){
(function(){
let sr = document.querySelectorAll('.my-star');
let i = 0;
//loop through stars
while (i < sr.length){
//attach click event
sr[i].addEventListener('click', function(){
//current star
let cs = parseInt(this.getAttribute("data-star"));
//output current clicked star value
document.querySelector('#output').value = cs;
/*our first loop to set the class on preceding star elements*/
let pre = cs; //set the current star value
//loop through and set the active class on preceding stars
while(1 <= pre){
//check if the classlist contains the active class, if not, add the class
if(!document.querySelector('.star-'+pre).classList.contains('is-active')){
document.querySelector('.star-'+pre).classList.add('is-active');
}
//decrement our current index
--pre;
}//end of first loop
})//end of click event
i++;
}//end of while loop
})();//end of function
})
If we run this code, we will see that it's close to perfection
Here's the result when I select 5 stars
Now there's an issue.
When I click on 2 stars, the succeeding stars should have removed the class is-active and the preceding stars should have reserved the class but it's not the case because the succeeding stars still reserved the class is-active.
This calls for the second loop which will increment and check if the succeeding stars contain the class is-class and remove it.
The second loop (included)
document.addEventListener('DOMContentLoaded', function(){
(function(){
let sr = document.querySelectorAll('.my-star');
let i = 0;
//loop through stars
while (i < sr.length){
//attach click event
sr[i].addEventListener('click', function(){
//current star
let cs = parseInt(this.getAttribute("data-star"));
//output current clicked star value
document.querySelector('#output').value = cs;
/*our first loop to set the class on preceding star elements*/
let pre = cs; //set the current star value
//loop through and set the active class on preceding stars
while(1 <= pre){
//check if the classlist contains the active class, if not, add the class
if(!document.querySelector('.star-'+pre).classList.contains('is-active')){
document.querySelector('.star-'+pre).classList.add('is-active');
}
//decrement our current index
--pre;
}//end of first loop
/*our second loop to unset the class on succeeding star elements*/
//loop through and unset the active class, skipping the current star
let succ = cs+1;
while(5 >= succ){
//check if the classlist contains the active class, if yes, remove the class
if(document.querySelector('.star-'+succ).classList.contains('is-active')){
document.querySelector('.star-'+succ).classList.remove('is-active');
}
//increment current index
++succ;
}
})//end of click event
i++;
}//end of while loop
})();//end of function
})
That should do it.
Now if we select 5 stars, all the preceding star elements will contain the class is-active
And if we select 1 star, all succeeding star elements will not contain the class is-active
So I can say that it's perfect now.
You can easily achieve this using CSS but my article today is about its implementation in JavaScript.
I am currently test-running a SAAS app that I built to collect customer reviews for your website, company, or business and help you to manage them. I used this code to collect the rating, and PHP in the backend to process it.