I have a rating system where users can rate items from 1 to 5. I used Font Awesome to display 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>
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.
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')
})
}
And voila!
Would you have done something differently? Feel free to share you ideas in the comments!
Top comments (4)
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...
thanks for this tip!
I look forward to the day we have :has() in CSS so we can do something like this.
Here is what you can do now in the sense of no JavaScript + minimalistic CSS + maintain accessibility.
Biggest advantage here is the super tiny CSS to achieve all the features. The greatest downside is that arrow controls work in reverse of expectation, you could change that with JavaScript if you want to maintain a minimalistic CSS (or by using
:has
instead and restoring elements to the correct order).