DEV Community

Angie Jones
Angie Jones

Posted on

Using Slice for Star Rating Effect

I have a rating system where users can rate items from 1 to 5. I used Font Awesome to display 5 unfilled stars.

5 unfilled stars

<div id="stars">
    <i class="fa-2x far fa-star gold-text" onclick="vote(1)"></i>
    <i class="fa-2x far fa-star gold-text" onclick="vote(2)"></i>
    <i class="fa-2x far fa-star gold-text" onclick="vote(3)"></i>
    <i class="fa-2x far fa-star gold-text" onclick="vote(4)"></i>
    <i class="fa-2x far fa-star gold-text" onclick="vote(5)"></i>
</div>
Enter fullscreen mode Exit fullscreen mode

When a user clicks on one of the stars, I'd like to add some sort of effect. I'm a bit too lazy to fight with CSS today in order to implement some cool animation, so instead I'm just going to use JavaScript to display an effect.

5 stars. Stars 1, 2, and 3 are filled. Stars 4 and 5 are unfilled

Inside of the vote() function, I get an array of all of the star elements, and I want to fill in all of the stars... up to the one the user clicked.

To do this, I chose to use the slice function. slice allows you to capture a subset of the array to further work on, which is perfect in my case because unless they choose a 5-star rating, I only need to fill in a subset of the stars.

slice allows you to specify what should be the first element of the sub-array, and optionally where the slicing should end (this ending index is not inclusive so is not a part of the new array. The element right before this index will be the last element of the resulting array).

Let's say the user wants to leave 3 stars. That means, I need to fill in the 1st, 2nd, and 3rd stars. So, my arguments would be 0 and 3, meaning begin the slice at the first element of the array, and stop when you get to index 3 (note that index 3 would be the 4th star and we don't want this included).

Once I have this sliced array, I can further operate on it.

To fill in the stars, I changed the Font Awesome class for each star in my sliced subset from far to fas (the solid option of this icon).

function vote(rating) {
    $('#stars i')
        .slice(0, rating)
        .each(function(){
            $(this).toggleClass('far fas')
        })
}
Enter fullscreen mode Exit fullscreen mode

And voila!

Animated image demonstrating clicking the 3rd star and stars 1, 2, and 3 go from unfilled to solid

Would you have done something differently? Feel free to share you ideas in the comments!

Oldest comments (4)

Collapse
 
link2twenty profile image
Andrew Bone

I look forward to the day we have :has() in CSS so we can do something like this.

Collapse
 
ashleyjsheridan profile image
Ashley Sheridan

It would be more accessible to build the stars as a series of radio buttons. You would automatically gain keyboard functionality and it would present to screen readers as a more suitable control type.

I did something like this a while back github.com/AshleyJSheridan/accessi...

Collapse
 
techgirl1908 profile image
Angie Jones

thanks for this tip!