Reputation: 3785
Actually i'm trying to make a star rating but i'm not able to understand how to make it properly. What is best way to make it?
What i tried:-
$(document).ready(function(){
$('.ratingUl li').mouseover(function(){
$(this).find('i').addClass('bg-yellow');
});
$('.ratingUl li').mouseout(function(){
// $(this).find('i').removeClass('bg-yellow');
});
$('.ratingUl li').click(function(){
$(this).find('i').addClass('bg-yellow');
var ratedValue = $(this).find('i').attr('value');
});
});
.position-relative{ position: relative;}
.ratingUl{ margin: 0px; padding: 0px;}
.ratingUl li{ list-style: none; display: inline;}
.bg-yellow{ color:orange;}
.hide{ display: none;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
<div class="container p-5">
<ul class="ratingUl">
<li> <i class="fas fa-star" value="1"></i> </li>
<li> <i class="fas fa-star" value="2"></i> </li>
<li> <i class="fas fa-star" value="3"></i> </li>
<li> <i class="fas fa-star" value="4"></i> </li>
<li> <i class="fas fa-star" value="5"></i> </li>
</ul>
</div>
Upvotes: 1
Views: 224
Reputation: 7295
The standard behavior is, when the user trigger a mouseover
event over a start, to mark that one and all the previous ones and to unmark the rest of them.
.prevAll()
to select the siblings before the current start..addBack()
to include the current one in the selection..nextAll()
to find the rest of them.$(document).ready(function(){
$('.ratingUl li').mouseover(function(){
$(this).prevAll().addBack().find('i').addClass('bg-yellow');
$(this).nextAll().find('i').removeClass('bg-yellow');
console.log( $('.ratingUl li i.bg-yellow').length );
});
});
.position-relative{ position: relative;}
.ratingUl{ margin: 0px; padding: 0px;}
.ratingUl li{ list-style: none; display: inline;}
.bg-yellow{ color:orange;}
.hide{ display: none;}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.2/css/all.css" integrity="sha384-/rXc/GQVaYpyDdyxK+ecHPVYJSN9bmVFBvjA/9eOB+pb3F2w2N6fc5qB9Ew5yIns" crossorigin="anonymous">
<div class="container p-5">
<ul class="ratingUl">
<li> <i class="fas fa-star" value="1"></i> </li>
<li> <i class="fas fa-star" value="2"></i> </li>
<li> <i class="fas fa-star" value="3"></i> </li>
<li> <i class="fas fa-star" value="4"></i> </li>
<li> <i class="fas fa-star" value="5"></i> </li>
</ul>
</div>
I would do it in a different way: just count how many starts have the .bg-yellow
class applied.
console.log( $('.ratingUl li i.bg-yellow').length );
Upvotes: 2
Reputation: 417
You can try it like this for CSS:
<style>
#star-rating li {
display: inline-block;
}
#star1:hover, #star2:hover, #star3:hover, #star4:hover, #star5:hover,
#star2:hover ~ #star1, #star3:hover ~ #star1, #star3:hover ~ #star2,
#star4:hover ~ #star1, #star4:hover ~ #star2, #star4:hover ~ #star3,
#star5:hover ~ #star1, #star5:hover ~ #star2, #star5:hover ~ #star3,
#star5:hover ~ #star4 {
color: orange;
}
</style>
HTML:
<ul id="star-rating">
<li><span onclick="testfunc(1)"><i id="star1" class="fas fa-star"></i></span></li>
<li><span onclick="testfunc(2)"><i id="star2" class="fas fa-star"></i></span></li>
<li><span onclick="testfunc(3)"><i id="star3" class="fas fa-star"></i></span></li>
<li><span onclick="testfunc(4)"><i id="star4" class="fas fa-star"></i></span></li>
<li><span onclick="testfunc(5)"><i id="star5" class="fas fa-star"></i></span></li>
</ul>
JS:
<script>
starValue => {
alert('Star Rating Selected: ' + starValue);
}
</script>
Should work :)
If not you can replace the '~' in CSS by '+'
Upvotes: 0
Reputation: 980
You can do it this way. I created small plugin for this. you can find it here.
Demo : https://malithmcr.github.io/Better-Rating/
Download : https://github.com/malithmcr/Better-Rating
;(function($){
$.fn.extend({
betterRating: function( options ) {
/**
* @option : wrapper - rating list wrapper div
* @option : icon - fontAwesome icon name
*/
this.defaultOptions = {
wrapper: '#list',
icon: 'fa fa-star',
};
var settings = $.extend({}, this.defaultOptions, options);
this.getRating(settings);
return this.each(function() {
var $this = $(this);
});
},
getRating: function(settings) {
var self = this;
$('.rating i').on('click', function(){
$('#rating-count').val($(this).data('rate'));
$(this).parent().find('i:lt(' + ($(this).index() + 1) + ')').addClass('selected');
});
$('.rating i').on('mouseover', function(){
$(this).parent().children('.rating i').each(function(e){
$(this).removeClass('selected');
});
$(this).parent().find('i:lt(' + ($(this).index() + 1) + ')').addClass('hover');
}).on('mouseout', function(){
$(this).parent().children('.rating i').each(function(e){
$(this).removeClass('hover');
});
});
$(this).submit(function( event ) {
event.preventDefault();
var formData = $(this).serializeArray();
console.log(formData);
$('#better-rating-list').append(self.template(formData));
});
},
/** creation of the list template*/
template: function(data) {
var rating = '<i class="fa fa-star selected" data-rate="1"></i>';
for(var i =1; i < data[1].value; i++) {
rating += '<i class="fa fa-star selected" data-rate="1"></i>';
}
var list = '<li>';
list += '<div class="profile-rating-wrapper">';
list += ' <div class="profile-pic"><img src="images/profile_pic.png" alt="" /></div>';
list += '<div class="name">'+data[0].value+' Wrote:</div>';
list += '<div class="rating">'
list += rating;
list += '</div>';
list += '</div>';
list += '<div class="content">';
list += '<p>'+data[2].value+'</p>';
list += '</div>';
list += '</li>';
return list;
}
});
Upvotes: 1