I have a js code that works, but the problem is that when I use it on the main HTML page, for some reason it only works on the first picture, although the LIKE icon is on all the pictures.
I do not understand why it is used only on the first value of the icon and not on the others.
How to make it work on all LIKE icons?
const likeIcon = document.getElementById('like-icon');
const likeCount = document.getElementById('like-count');
likeIcon.onclick = () => {
const newId = likeIcon.getAttribute('data-news');
const url = `/like_news/${parseInt(newId)}/`;
fetch(url, {
method: 'GET',
headers: {
'Content-type': 'applicatin/json'
}
})
.then(response => {
return response.json();
})
.then(data => {
if(data.liked) {
likeIcon.classList.remove('empty-heart');
}
else {
likeIcon.classList.add('empty-heart');
}
likeCount.innerHTML = data.like_count;
})
.catch(error => {
console.log(error);
})
}
HTML CODE
<section class="trend">
<div class="container">
<div class="flex align-center justify-between trend-header">
<h2 class="subtitle">
<i class="ri-fire-line subtitle-icon"></i>
В тренде
</h2>
<button class="btn btn-outline">Посмотреть все</button>
</div>
<div class="trend-content">
{% for new in news|slice:"2" %}
<div class="trend-card">
<img src="{{new.banner.url}}" alt="newsPhoto" class="trend-background" />
<div class="card-header">{{new.category.title}}</div>
<div class="card-bottom">
<h3 class="card-title">
{{new.title}}
</h3>
<div class="card-btn">
<div class="count" id="like-count">{{new.likes.count}}</div>
{% if liked_by %}
<button class="btn-up" class="fa fa-heart">
<li><a href="javascript:void(0);"><i id="like-icon" data-news="{{new.id}}" class="fa fa-heart"></i></a></li>
</button>
{% else %}
<button class="btn-up" class="fa fa-heart empty-heart">
<li><a href="javascript:void(0);"><i id="like-icon" data-news="{{new.id}}" class="fa fa-heart empty-heart"></i></a></li>
</button>
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
</section>
Tried to use https://developer.mozilla.org/en/docs/Web/API/Document/querySelectorAll but couldn’t do it
const likeIcon = document.querySelectorAll('#like-icon');
const likeCount = document.getElementById('like-count');
likeIcon.forEach(like-icon => {
like-icon.addEventListener("click", () => {
const newId = likeIcon.getAttribute('data-news');
const url = `/like_news/${parseInt(newId)}/`;
fetch(url, {
method: 'GET',
headers: {
'Content-type': 'applicatin/json'
}
})
.then(response => {
return response.json();
})
.then(data => {
if(data.liked) {
likeIcon.classList.remove('empty-heart');
}
else {
likeIcon.classList.add('empty-heart');
}
likeCount.innerHTML = data.like_count;
})
.catch(error => {
console.log(error);
})
});
}
}
And i expected it to work for all pictures that I had on main HTML page
>Solution :
It looks like you’re on the right track using querySelectorAll to get all the like icons. However, there is a small mistake in your code when you use likeIcon instead of like-icon in your forEach loop.
Try replacing your JS code with the following, which should work for all like icons:
const likeIcons = document.querySelectorAll('#like-icon');
const likeCounts = document.querySelectorAll('#like-count');
likeIcons.forEach((likeIcon, index) => {
likeIcon.addEventListener('click', () => {
const newId = likeIcon.getAttribute('data-news');
const url = `/like_news/${parseInt(newId)}/`;
fetch(url, {
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
.then(response => {
return response.json();
})
.then(data => {
if (data.liked) {
likeIcons[index].classList.remove('empty-heart');
} else {
likeIcons[index].classList.add('empty-heart');
}
likeCounts[index].innerHTML = data.like_count;
})
.catch(error => {
console.log(error);
});
});
});
This code should loop through all the like icons and add a click event listener to each of them. When a user clicks on a like icon, the corresponding like count and icon should update based on the server response.
Note that we are using querySelectorAll to get all the like icons and like counts, and then we are looping through them using forEach. We are also using the index of each like icon to update the correct like count and icon.