Reputation: 113
I'm trying to display the current rating image for example 3 stars along with its rating definition when the user clicks the desired rating and have it stay on that rating until the user picks a different rating.
Or have the rating jump back to the rating the user has currently picked when the user hovers over other rating values with out choosing (clicking) a different rating.
So far I can only display the rating images and definitions when the user hovers over them, but not when the user clicks on them.
HTML
<form action="" method="post">
<ul class="rating notrated">
<li id="rate-1" data-desc="Bad">
<label for="rating-1"><input type="radio" value="1" name="rating" id="rating-1" />1 star</label>
</li>
<li id="rate-2" data-desc="Good">
<label for="rating-2"><input type="radio" value="2" name="rating" id="rating-2" />2 stars</label>
</li>
<li id="rate-3" data-desc="Great">
<label for="rating-3"><input type="radio" value="3" name="rating" id="rating-3" />3 stars</label>
</li>
<li id="rate-4" data-desc="Better">
<label for="rating-4"><input type="radio" value="4" name="rating" id="rating-4" />4 stars</label>
</li>
<li id="rate-5" data-desc="Best">
<label for="rating-5"><input type="radio" value="5" name="rating" id="rating-5" />5 stars</label>
</li>
</ul>
<div class="rate">Rate this product</div>
</form>
Jquery
$(document).ready(function(){
$('.rating li')
.on('mouseenter touchstart', function() {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix);
$('.rating').nextAll().removeClass('notrated');
$('.rate').text($(this).attr('data-desc'));
})
.on('mouseleave touchend', function() {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().removeClass('rating-' + classSuffix);
$('.rate').text('Rate this product');
});
});
CSS
.rating{
height: 30px;
}
.notrated{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px 0px;
}
.rating-1{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px -30px;
}
.rating-2{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px -60px;
}
.rating-3{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px -90px;
}
.rating-4{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px -120px;
}
.rating-5{
background-image: url('./stars.png');
background-repeat: repeat-x;
background-position: 0px -150px;
}
Upvotes: 1
Views: 303
Reputation: 2791
Add change
event separately for checkbox
to maintain the "RATED" text after the mouse leave.
$(document).ready(function () {
var checked = false, checkedElem;
$('.rating li')
.on('mouseenter touchstart', function () {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix);
$('.rating').nextAll().removeClass('notrated');
$('.rate').text($(this).attr('data-desc'));
})
.on('mouseleave touchend', function () {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
if (checked) {
var classSuffix1 = checkedElem.attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix1);
$('.rating').nextAll().removeClass('notrated');
$('.rate').text(checkedElem.closest('li').attr('data-desc'));
}
else {
$('.rating').prevAll().addBack().removeClass('rating-' + classSuffix);
$('.rate').text('Rate this product');
}
});
$('.rating li input')
.on('change', function () {
checkedElem = $(this);
var classSuffix = checkedElem.attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix);
$('.rating').nextAll().removeClass('notrated');
$('.rate').text(checkedElem.closest('li').attr('data-desc'));
checked = true;
})
});
UPDATE:
Upvotes: 1
Reputation: 34168
This should: vary the rating until one is clicked (with mouse over). When one IS clicked (selected) then it keeps that rating until it is changed.
$(document).ready(function() {
$('.rating li').on('mouseenter touchstart', function() {
var checked = $('input[type=radio]:checked');
var hasCheck = checked.length;
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix);
$('.rating').nextAll().removeClass('notrated');
if (hasCheck) {
$('.rate').text(checked.parents('li').data('desc'));
} else {
$('.rate').text($(this).data('desc'));
}
})
.on('mouseleave touchend', function() {
var hasCheck = $('input[type=radio]:checked').length;
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().removeClass('rating-' + classSuffix);
if (!hasCheck) {
$('.rate').text('Rate this product');
}
})
.on('change click', 'input[type=radio]', function() {
var checked = $('input[type=radio]:checked');
var hasCheck = checked.length;
if (hasCheck) {
$('.rate').text(checked.parents('li').data('desc'));
} else {
$('.rate').text('Rate this product');
}
});
});
NOTE: this also takes care of issues if it gets changed with code: i.e.
$('input[type=radio]').prop("checked", false);
$('input[type=radio]').trigger('change');
Play around with it here: http://jsfiddle.net/MarkSchultheiss/Lczv8zzj/
Upvotes: 1
Reputation: 7442
I did a little modification to you code and added a click handler.
$(document).ready(function() {
$('.rating li')
.on('mouseenter touchstart', function() {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().addClass('rating-' + classSuffix);
$('.rating').nextAll().removeClass('notrated');
$('.rate').text($(this).attr('data-desc'));
})
.on('mouseleave touchend', function() {
var classSuffix = $(this).find('input').attr('id').split('-')[1];
$('.rating').prevAll().addBack().removeClass('rating-' + classSuffix);
$('.rate').text($('.rate').attr('data-desc'));
})
.on('click', function() {
$('.rate').attr('data-desc', $(this).attr('data-desc'))
});
});
I also added the initial description to data-desc
attriubute of .rate
element
<div data-desc="Rate this product" class="rate">Rate this product</div>
Check out the jsFiddle
Upvotes: 2