im having some issues with my star rating on a webpage.
i have a foreach loop where product details and a star rating are displayed for each product in my list.
However, now i am having the following issues:
- when i first select the stars on the first product, all is good
- when i click on the stars for the next product, it affects the rating for the first one
any help would be good!
This is part of the html
@foreach (var purchase in purchaseHistories)
{
<div class="card rounded-3 mb-4">
<div class="card-body p-4">
<div class="row d-flex justify-content-between align-items-center">
<div class="col-md-2 col-lg-2 col-xl-2">
<img src="@purchase.ImageUrl" alt="@purchase.Name" class="img-fluid rounded-3" >
</div>
<div class="col-md-3 col-lg-3 col-xl-3">
<p class="lead fw-normal mb-2">@purchase.Name</p>
<p><span class="text-muted">@purchase.Description</span></p>
<p><span class="text-muted">Purchased On: @purchase.PurchaseDate</span></p>
<p><span class="text-muted">Quantity: @purchase.Quantity</span></p>
<button type="button" class="btn btn-primary">Download</button>
</div>
<div class="col-md-3 col-lg-3 col-xl-2 d-flex flex-column">
<div class="star-rating-container" >
<label for="star">Review:</label>
<div>
<button class="star" type="button">☆</button>
<button class="star" type="button">☆</button>
<button class="star" type="button">☆</button>
<button class="star" type="button">☆</button>
<button class="star" type="button">☆</button>
</div>
</div>
<label for="Activation Code">Activation Code: </label>
<select class="form-select" aria-label="Activation Code">
@{
var split = purchase.ActivationCode.Split(",");
var val = 0;
}
@for (int i = 0; i < split.Length; i++)
{
if (i == 0)
{
<option selected>@split[i]</option>
}
else
{
val += 1;
<option value="@val">@split[i]</option>
}
}
</select>
</div>
this is part of the javascript
const products=document.querySelectorAll('.product')
const allstars = document.querySelectorAll('.star');
allstars.forEach((star, i) => {
star.onclick = function () {
let currentstar = i + 1;
console.log(currentstar);
allstars.forEach((star, j) => {
if (currentstar >= j + 1) {
star.innerHTML = '★';
} else {
star.innerHTML = '☆';
}
})
}
})
i tried adding another class to the star rating container but it doesnt seem to work..i dont know how to adjust this so that the id for each star rating container for each purchase can be individually contained
2
Answers
This type of elements do not require JS at all these days. Everything can be done with modern CSS and old good radios. Collect the radios in one
flex-direction: row-reverse
container with those radios aligned in reverse order, add a decoration element if needed and rely on some sort of ainput:checked ~ .deco
selector.Here’s a codepen example:
https://codepen.io/JaredSpb/pen/VwEjRoP
But lets fix your code aswell. With a click you dont need to loop over all the stars at the page. Just loop over previous elements:
You need to define class
.stars
as a parent of.star
and loop over the.stars
to get the rating function works.