'Dynamically get value of specific element from list of elements with same id
So I'm trying to make a star rating feature and I'm stuck on setting the value dynamically from a variable. I don't want to make it so that the stars are interactive. I want them to be set or filled using the variable's value.
This is how I'm getting the stars
<div>
<span></span>
<span class="rating" data-rating="0">
<i class="star" data-checked="false" data-note="1">★</i>
<i class="star" data-checked="false" data-note="2">★</i>
<i class="star" data-checked="false" data-note="3">★</i>
<i class="star" data-checked="false" data-note="4">★</i>
<i class="star" data-checked="false" data-note="5">★</i>
</span>
<span>
<input class="coach-id" hidden value="{{ coach.id }}">
</span>
</div>
Now, my issue is that I'm generating this block of code n amount of times for as many entries as I have in my database. This creates an issue that every block will have the same class.
I want to be able to set them dynamically through a variable specific to each block. Meaning every entry in the DB will have a rating column which will be the value of the stars corresponding to that entry.
Right now, the stars are interactive through the following script
const ratings = document.querySelectorAll('.rating');
const coach_id = document.querySelector('.coach-id').value;
ratings.forEach(rating =>
rating.addEventListener('mouseleave', ratingHandler)
);
const stars = document.querySelectorAll('.rating .star');
stars.forEach(star => {
star.addEventListener('mouseover', starSelection);
star.addEventListener('mouseleave', starSelection);
star.addEventListener('click', activeSelect);
});
function ratingHandler(e) {
const childStars = e.target.children;
for(let i = 0; i < childStars.length; i++) {
const star = childStars.item(i)
if (star.dataset.checked === "true") {
star.classList.add('hover');
}
else {
star.classList.remove('hover');
}
}
}
function starSelection(e) {
const parent = e.target.parentElement
const childStars = parent.children;
const dataset = e.target.dataset;
const note = +dataset.note; // Convert note (string) to note (number)
for (let i = 0; i < childStars.length; i++) {
const star = childStars.item(i)
if (+star.dataset.note > note) {
star.classList.remove('hover');
} else {
star.classList.add('hover');
}
}
}
function activeSelect(e) {
const parent = e.target.parentElement
const childStars = parent.children;
const dataset = e.target.dataset;
const note = +dataset.note; // Convert note (string) to note (number)
for (let i = 0; i < childStars.length; i++) {
const star = childStars.item(i)
if (+star.dataset.note > note) {
star.classList.remove('hover');
star.dataset.checked = "false";
} else {
star.classList.add('hover');
star.dataset.checked = "true";
}
}
const noteTextElement = parent.parentElement.lastElementChild.children.item(0)
noteTextElement.innerText = `Note: ${note}`;
console.log(note);
let url = `/coach/editRating/${coach_id}/${note}`
window.location.href = url
console.log(url)
}
Solution 1:[1]
Hi @Moudhaffer Bouallegui - Please find the sample star rating page.
document.querySelectorAll("i.fa-star").forEach(function(element,position){
element.addEventListener("click",function(){
this.style.color = "yellow";
// this.style.fontSize = "35px";
let noOfStar = this.parentNode.parentNode.querySelector("input[name=star]").value;
document.querySelectorAll("i.fa-star").forEach(function(e,p){
e.style.color = "rgb(126, 126, 126)";
if((p+1) <= noOfStar){
e.style.color = "yellow";
}
})
})
})
input[type=radio]{
display: none;
}
.card{
max-width: 350px;
text-align: center;
margin: auto;
box-shadow: 0 0 15px 0 #000;
padding: 15px;
background-color: #000;
color: #fff;
cursor : pointer;
}
.fa-star{
font-size: 30px;
color: rgb(126, 126, 126);
transition: 0.1s ease-in-out all;
}
.stars{
padding:10px;
height: 40px;
}
button{
width: 70%;
outline: none;
border: none;
background-color: rgb(107, 107, 107);
padding:10px;
color: #fff;
border-radius: 0;
}
button:hover{
box-shadow: 0 0 30px 0 yellow;
border: 1px solid #fff;
}
.fa-star{
cursor: pointer;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="card">
<h2>Give your stars</h2>
<div class="stars">
<span><label><i for="star1" class="fa fa-star"></i></label><input type="radio" name="star" id="star1"
value="1"></span>
<span><label><i for="star2" class="fa fa-star"></i></label><input type="radio" name="star" id="star2"
value="2"></span>
<span><label><i for="star3" class="fa fa-star"></i></label><input type="radio" name="star" id="star3"
value="3"></span>
<span><label><i for="star4" class="fa fa-star"></i></label><input type="radio" name="star" id="star4"
value="4"></span>
<span><label><i for="star5" class="fa fa-star"></i></label><input type="radio" name="star" id="star5"
value="5"></span>
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ganesh R |
