Star Rating with radio group

by Kamruz Jaman

HTML

<div class="control-group">
    <label class="control-label" for="review-rating">Rating</label>
    <div class="controls rating">
        <label>
            <input type="radio" name="review-rating" value="1" />1</label>
        <label>
            <input type="radio" name="review-rating" value="2" />2</label>
        <label>
            <input type="radio" name="review-rating" value="3" />3</label>
        <label>
            <input type="radio" name="review-rating" value="4" />4</label>
        <label>
            <input type="radio" name="review-rating" value="5" />5</label>
    </div>
</div>

CSS

.starRating input { display:none; }

.starRating label { 
    width: 18px; 
    height: 16px; 
    display: inline-block;
    text-indent: -9999px; /* hide the label text off screen */
    background: url("http://designmoo.com/wp-content/uploads/2011/01/rating_stars.png") -155px -32px;
}

.starRating label.on { 
    background-position: -155px -76px;
}

JavaScript

$('.controls.rating')
    .addClass('starRating') //in case js is turned off, it fals back to standard radio button
    .on('mouseenter', 'label', function(){
            DisplayRating($(this)); // when we hover into a label, show the ratings
        }
    )
    .on('mouseleave', function() {
        // when we leave the rating div, figure out which one is selected and show the correct rating level
        var $this = $(this),
            $selectedRating = $this.find('input:checked');
        
        if ($selectedRating.length == 1) {
            DisplayRating($selectedRating.parent()); // a rating has been selected, show the stars
        } else {
            $this.children().removeClass('on'); // nothing clicked, remove the stars
        };
    }
);

var DisplayRating = function($el){
    // for the passed in element, add the 'on' class to this and all prev labels
    // and remove the 'on' class from all next labels. This stops the flicker of removing then adding back
    $el.addClass('on').prevAll().addClass('on');
    $el.nextAll().removeClass('on');
};