vignesh vignesh - 15 days ago 4
CSS Question

convert radio buttons to star rating

I am trying to convert the radio buttons in the form to star rating

I am using nintex forms and the way it has DOM structure for the radio button is as below

<table class="controls rating">
<tr>
<td>
<span>
<input type="radio" name="review-rating" id="1" value="1" />
<label for="1">1</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="2" id="2" />
<label for="2">2</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="3" id="3" />
<label for="3">3</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="4" id="4" />
<label for="4">4</label>
</span>
</td>
<td>
<span>
<input type="radio" name="review-rating" value="5" id="5" />
<label for="5">5</label>
</span>

</td>
</tr>
</table>


Now I found a jsfiddle which does what I expected, but the dom structure was different

I made some tweaks and got the radio buttons appear as star, but its not working as expected

Here is the fiddle

I want the star rating on top to work like the star rating in bottom.

enter image description here

P.S: Its ok if the bottom one doesn't work after changes. I just want the star rating to be working for my DOM structure(top one in fiddle)

Answer

Try this, I just added the undo

        $('.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); // a rating has been selected, show the stars
            if ($selectedRating.val() == 5) {
                $this.find('label').addClass('on');
            }
        } else {
            $this.find('label').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');
    $el.parent('label').addClass('on');
    $el.closest('td').prevAll().find('label').addClass('on');
    $el.closest('td').nextAll().find('label').removeClass('on');
};

Edit: I just notice a bug lately so I edited it and fix the bug

JS Fiddle

Comments