Итак, я пытаюсь создать функцию звездного рейтинга, и я застрял на динамической установке значения из переменной. Я не хочу делать так, чтобы звезды были интерактивными. Я хочу, чтобы они были установлены или заполнены с использованием значения переменной.
Вот как я получаю звезды
<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>
Теперь моя проблема в том, что я генерирую этот блок кода n
столько раз, сколько записей есть в моей базе данных. Это создает проблему, что каждый блок будет иметь один и тот же класс.
Я хочу иметь возможность устанавливать их динамически через переменную, специфичную для каждого блока. Это означает, что каждая запись в БД будет иметь столбец рейтинга, который будет значением звезд, соответствующим этой записи.
Прямо сейчас звезды интерактивны через следующий скрипт
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.info(note);
let url = `/coach/editRating/${coach_id}/${note}`
window.location.href = url
console.info(url)
}
@T.J.CrowderT.J.Crowder Прошу прощения, я имел в виду класс, а не идентификатор, я исправлю себя. Что касается второго вопроса, каждый блок html-звезд создается внутри цикла for (TWIG, я работаю с Symfony). Теперь каждая итерация цикла в основном отображает запись в Table Coach в моей БД. Таким образом, каждый блок звездочек, созданный в каждой итерации, конкретно связан с этой записью или строкой, отображаемой в этой итерации. Теперь в этой таблице у меня есть столбец рейтинга со значениями, уникальными для каждой строки или записи. Я получаю эти значения и хочу установить с ними соответствующие звезды.
в чем именно проблема?:
@Don'tPanic Проблема в том, что я не знаю, как установить для каждой звезды значение, соответствующее ей, независимо от других звезд. Вы можете думать о каждом наборе звезд как о Личности. Затем этот человек имеет рейтинг, хранящийся в БД. Я могу получить эту переменную для всех лиц и передать ее шаблону с идентификатором этого человека в ассоциативном массиве без проблем. Но я не знаю, как тогда связать, например, первую пару идентификатора человека и рейтинга с набором звезд. Вторая проблема заключается в том, что я не мог понять, как установить звезды визуально, я имею в виду.
AFAICT все JS, которые вы показали, связаны с интерактивностью - ввод/вывод мыши и клики? А твой вопрос ни о чем, а ведь говорит "Я не хочу делать так, чтобы звезды были интерактивными"...? Я бы предложил отредактировать ваш вопрос и сосредоточиться только на одной проблеме, с которой вы столкнулись. Попробуйте создать минимальный, полный и проверяемый пример. Наконец, 5-звездочные рейтинговые системы в Javascript чрезвычайно распространены, и здесь, на SO, есть сотни связанных вопросов и ответов. Если вы не знаете, с чего начать, они могут быть вам полезны.
Привет, @Moudhaffer Bouallegui. Пожалуйста, найдите образец страницы рейтинга.
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>
Я очень ценю ваш ответ, но это позволяет мне создавать интерактивные звезды, которые я могу щелкнуть, чтобы установить. Что я хочу сделать, так это установить звезды, когда страница загружается со значениями из БД. У меня есть значения, но я не могу понять, как установить звезды при загрузке страницы