Below is the code, word for word from the book’s exercise files.
The code builds a system for users to rate their favorite celebrities based on 1-4 stars. Each half star is represented by an HTML radio button, which are each replaced with <a> tags, using background images for the stars.
Everything seems to work fine except that when you click a star/radio button, all subsequent radio buttons are assigned the “checked” attribute. If this were for a real application, and the data was being saved, additional logic would be needed to find the actual radio button/rating the user selected.
This snippet of code is what assigns the “checked” attribute:
$allLinks
.parent()
.find('input:radio[value=' + $star.text() + ']')
.attr('checked', true);
Unless I’m missing something in the remainder of the code, I don’t see why this is adding the checked attribute to all lesser radio inputs as well.
Entire code:
$(document).ready(function(){
starRating.create('.stars');
});
// The widget
var starRating = {
create: function(selector) {
// loop over every element matching the selector
$(selector).each(function() {
var $list = $('<div></div>');
// loop over every radio button in each container
$(this)
.find('input:radio')
.each(function(i) {
var rating = $(this).parent().text();
var $item = $('<a href="#"></a>')
.attr('title', rating)
.addClass(i % 2 == 1 ? 'rating-right' : '')
.text(rating);
starRating.addHandlers($item);
$list.append($item);
if($(this).is(':checked')) {
$item.prevAll().andSelf().addClass('rating');
}
});
// Hide the original radio buttons
$(this).append($list).find('label').hide();
});
},
addHandlers: function(item) {
$(item).click(function(e) {
// Handle Star click
var $star = $(this);
var $allLinks = $(this).parent();
// Set the radio button value
$allLinks
.parent()
.find('input:radio[value=' + $star.text() + ']')
.attr('checked', true);
// Set the ratings
$allLinks.children().removeClass('rating');
$star.prevAll().andSelf().addClass('rating');
// prevent default link click
e.preventDefault();
}).hover(function() {
// Handle star mouse over
$(this).prevAll().andSelf().addClass('rating-over');
}, function() {
// Handle star mouse out
$(this).siblings().andSelf().removeClass('rating-over')
});
}
}