I am working with a prior developers star rating code. I need to modify it because it doesn't operate the way the developer intended. If you look, there are label
elements with stars inside. You can see the first label
has 1 span
, while the 5th label
has 5 spans
.
An example of how it's working now is you click on the 5th input
the developer has 5 stars inside the label
, but to get it to work as intended I actually need to modify the other label spans as well. So, let's say the user chooses 3 stars, I'd need to mutate the span
inside labels 1, 2, and 3. For choosing 4 stars, I'd need to mutate the span
inside labels 1, 2, 3, and 4.
I was thinking about a jquery/javascript solution that traverses labels (maybe with ids). So if they click on input 4, the javascript solution would loop through all spans inside labels 1, 2, 3, and 4 and update the css. I'm not sure how to do this though.
<div class="rating-selector">
<label>
<input type="radio" name="rating" value="1" />
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="2" />
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="3" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="4" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="5" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
</div>
You could find the parent <label>
index by using .closest("label").index()
. Then, use the :lt()
selector to grab each item before it.
const highlightPrevious = (elem) => {
let $this = $(elem);
$(".rating-selector label span").css("color", ""); //reset styling
let idx = $this.index(); //get index of selected label
$(`.rating-selector label:lt(${idx+1}) span`).css("color", "red"); //style all label spans up to and including the selected index
};
$('label')
.click(function() { highlightPrevious(this); })
.mouseover(function() { $(this).click() });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rating-selector">
<label>
<input type="radio" name="rating" value="1" />
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="2" />
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="3" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="4" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
<label>
<input type="radio" name="rating" value="5" />
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
<span class="icon">★</span>
</label>
</div>