I'm trying to make a star based rating system.
First of all, I don't like to make it all with JS and only innerHTML the rated stars in a given div
. I want to make it more like a plugin with the ability to make anything votable and you just have to pass the classes.
My biggest problem, however, is that I'm setting classes on hover and removing them on mouse leave. That's just fine until the user clicks and the classes are set. Think you can imagine what happens if the user hovers again: The classes would get removed.
But still I want the user to be able to change his vote. I managed it with two different divs where one is hidden. I absolutely don't feel comfortable with this solution:
<div class="votable hide">
<i class="fa fa-3x fa-star-o" data-vote-type="1"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="2"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="3"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="4"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="5"></i>
</div>
<div class="voted">
<i class="fa fa-3x fa-star" data-vote-type="1"></i>
<i class="fa fa-3x fa-star" data-vote-type="2"></i>
<i class="fa fa-3x fa-star" data-vote-type="3"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="4"></i>
<i class="fa fa-3x fa-star-o" data-vote-type="5"></i>
</div>
With jQuery I'm enabling .votable
on hover. On click I'm setting the actual vote to .voted
and on mouse leave I'm hiding .votable
and showing .voted
.
$('.voted').hover(
function() {
$('.voted').addClass('hide');
$('.votable').removeClass('hide');
}
);
$('.votable').on('mouseleave',function(){
$('.voted').removeClass('hide');
$('.votable').addClass('hide');
});
$('.votable > i').hover(
function() {
$(this).prevAll().andSelf().removeClass('fa-star-o').addClass('fa-star');
$(this).nextAll().removeClass('fa-star').addClass('fa-star-o');
},
function() {
$(this).prevAll().andSelf().removeClass('fa-star').addClass('fa-star-o');
}
);
$('.votable > i').click(function(e) {
var vote_type = $(this).attr('data-vote-type');
var el = $('.voted > i[data-vote-type="' + vote_type + '"]');
$(el).prevAll().andSelf().removeClass('fa-star-o').addClass('fa-star');
$(el).nextAll().removeClass('fa-star').addClass('fa-star-o');
});
You can see the code working at my fiddle.
What would be a better way of achieving this?