In order to become a successful FrontEnd developer, it is very important to have a very strong understanding of HTML, CSS, and Javascript, and various topics like DOM and Critical rendering path. And this understanding and skill can be only built by solving various challenges and problems. Challenges can be of any type, it can be as easy as making a small calculator or creating a star rating widget from scratch but the only thing requires that you keep on bettering yourself each day.
This is a 7 series blog based on The DOM Challenge created and formulated by Sunny Puri (SDE2 at Swiggy) and Sadanand Pai (SDE2 at CoinDCX) in order to inspire and push the upcoming or already established developer to brush up their skills and deep-dive more to learn concepts lik̋e Asynchronous nature of JS or DOM manipulation.
Challenge 1: Star Rating
This is the first challenge from The DOM Challenge, creating a star rating utility using HTML, CSS, and JavaScript. For this challenge you would be provided with a simple template and using it you have to solve the challenge.
Note:- You can modify the code according to your style and convenience but make sure you follow all the rules.
Templates
For HTML,
<body>
<div id="star"></div>
<div id="display-star"></div>
<script src="script.js"></script>
</body>
To display the star we need to import the star icon from font awesome using CDN,
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css">
Star Icons,
<i class="fa fa-star"></i>
<i class="fa fa-star-o"></i>
Also read, What is a Callback Functions in JavaScript
CSS,
.fa-star-o:before {
content: "\f006";
color: #5f6368;
}
.fa-star:before {
content: "\f005";
color: #d56e0c;
}
Rules
There are a few rules by which your star rating system should abide,
- When you hover your mouse pointer over the stars, it should turn yellow.
- If the user enters their mouse at the middle or end, for example, If the user hovers his mouse at the number 4th star, all the stars from 1 to 4 should change their colors to yellow.
- If users remove the pointer from the stars without clicking over it all the stars should go back to their original state.
- Lastly, If the user clicks on a star, for example, If the user clicks on the 3rd star then, first all the stars till the 3rd should turn yellow and the rating number should be displayed below it.
Demo
Also read, Easy tutorial to build React Autosuggest from scratch
My Solution
My approach to this problem is very simple, first I have populated the body with a star icon to display 5 stars in a row. The container
div brings the icons to the middle of the webpage for aesthetic looks. And Inside the input-container
, I added a total 5 star-icons with class fa fa-star-o
elements to display empty 5-star icons.
Then, at last, I added an h2 tag with the rating
class to display the rating when the user clicks on the star, by default it displays 0.
HTML
<body>
<h1>Star Rating!!</h1>
<div class="container">
<div class="input-container">
<i class="fa fa-star-o"></i>
<i class="fa fa-star-o"></i>
<i class="fa fa-star-o"></i>
<i class="fa fa-star-o"></i>
<i class="fa fa-star-o"></i>
</div>
<h2 class="rating">0</h2>
</div>
<script src="script.js"></script>
</body>
CSS
Then I have added some CSS to make it look more attractive,
body {
text-align: center;
}
.container{
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.input-container{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.fa-star-o:before {
content: "\f006";
color: #5f6368;
font-size: 40px;
}
.fa-star:hover {
cursor: pointer;
}
.fa-star:before {
content: "\f005";
color: #d56e0c;
font-size: 40px;
}
.rating{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 60px;
}
Also read, JavaScript Functions | How does Function works in Js {Detail Explanation}
JS
In JS we will now add some functions and events which get triggered when the mouse hovers on the stars and when the user clicks on them.
let ratDisplay = document.querySelector('.rating');
let stars = document.querySelectorAll('.fa-star-o');
let totalStar = 0;
At first, we are using a document.querySelector('.rating')
method to get the reference of the rating div and save it in the ratDisplay
variable and document.querySelectorAll('.fa-star-o')
method is used to return the array of all the star-icons div having class fa-star-o
and a variable totalStar
is used to convert it to the default state of the star icon.
stars.forEach((star, index) => {
star.dataset.rating = index + 1;
star.addEventListener('mouseover', onMouseOver);
star.addEventListener('click', onClick);
star.addEventListener('mouseleave', onMouseLeave);
});
Now we will iterate through each star-icon div and attach the unique dataset id containing the value which later we can use it to find and differentiate the exact star-icon div on which the mouse is hovering. Also, we will attach three different events of the mouse, like mouseover
, click
and mouseleave
and pass onMouseOver
, onClick
, and onMouseLeave
callbacks which get called when the specific events get triggered.
function onMouseOver(e) {
const ratingVal = e.target.dataset.rating;
if (!ratingVal) {
return;
} else {
fill(ratingVal);
}
}
In mouseover
event we pass onMouseOver
callback which first checks and gets the id of the current star-icon div through e.target.dataset.rating
method on which the mouse is hovering and then pass the id to the fill
function.
function fill(ratingVal) {
for (let i = 0; i < 5; i++) {
if (i < ratingVal) {
stars[i].classList.replace('fa-star-o', 'fa-star');
} else {
stars[i].classList.replace('fa-star', 'fa-star-o');
}
}
}
Fill
function is the most important function here, In this function, we run a loop till 5, and check if the passed argument ratingVal
is greater than i
then we replace star-icon div containing fa-star-o
with fa-star
else we keep the star-icon div containing class fa-star-o
same or if it has class fa-star
then replace it with fa-star-o
.
function onMouseLeave(e) {
fill(totalStar);
}
In case of mouseleave
event, onMouseLeave
callback get triggers which simply call fill function and pass an argument totalStar
which has a current value of 0. And in the fill
function, as i
is not greater than the passed argument ratingVal
, thus we keep the star-icon div containing class fa-star-o
same or if it has class fa-star
then replace it with fa-star-o
.
function onClick(e) {
const ratingVal = e.target.dataset.rating;
totalStar = ratingVal;
fill(totalStar);
ratDisplay.innerHTML = ratingVal;
}
Lastly when the user clicks on any star-icon div, first we store totalStar
with the current id of star-icon div on which mouse is hovering and the pass it to fill
function. In fill
function as the passed argument ratingVal
is greater than i
, it replaces star-icon div containing fa-star-o
with fa-star
till the condition is true. And finally, we update the rating with the help of ratDisplay.innerHTML
method.
Demo
Also read, How JavaScript works with HTML you might not know
Final Words
I hope you like the article and if did then do comment and let me know about it. I will also be solving the rest of the challenges soon and will be posting a blog on each challenge with the solutions, bookmark this website to get more awesome article like these.
Also, you can check out more articles on JavaScript, Data Strictures and algorithms, and React, and if you are also interested in software or technology we also publish articles in these categories too.