Reputation: 192
I'm making a Marvel API project. I added a Like button so it could count the likes, but everytime I click any like button the only counter adding numbers is the first one. Can anyone tell me how I do this properly?
The problem is because the ID
is being made by a for, so how could I solve this?
This is my JS code (on the js file of my project) :
success: function(data)
{
footer.innerHTML = data.attributionHTML;
var string = "";
string += "<div class='row'>";
for (var i = 0; i < data.data.results.length; i++)
{
var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='" + element.thumbnail.path + "/portrait_fantastic." + element.thumbnail.extension + "'/>";
string += '<button class="btn btn-success" onClick="testo()"><i class="fas fa-thumbs-up"></i> | <a id="likes">0</a></button>';
string += "<h3>" + element.title + "</h3>";
string += "</div>";
if ((i + 1) % 4 == 0)
{
string += "</div>";
string += "<div class='row'>";
}
}
marvelContainer.innerHTML = string;
}
And this is my onclick function (It is on my html file because it wont work on my js file)
<script>
var likes=0;
function testo()
{
likes += 1;
document.getElementById("likes").innerHTML = likes;
}
</script>
Upvotes: 1
Views: 109
Reputation: 129
That is because all your buttons are being generated with the same id="likes"
and then you are changing the HTML with document.getElementById("likes").innerHTML = likes;
for your code to work properly you will need to use a different approach, maybe adding a data-* attribute to your buttons and then change the likes by the data-* atribute using .getAttribute('data-id-something').innerHTML
instead of document.getElementById("likes").innerHTML
.
Or even better in this case you can give the buttons a class name and handle it with: document.getElementsByClassName("like-btn")
You can check the last option in this example:
var init = function(data){
var string ="";
string += "<div class='row'>";
for(var i = 0; i<4; i++)
{
// var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='/portrait_fantastic.jgeg'/>";
string += '<button class="btn btn-success" onClick="testo('+i+')"><i class="fas fa-thumbs-up"></i> | <span class="like-btn">0</span></button>';
string += "<h3>Element title</h3>";
string += "</div>";
if((i+1) % 4 ==0)
{
string += "</div>";
string += "<div class='row'>";
}
}
document.getElementById("marvelContainer").innerHTML = string;
}
init();
<script>
var likes=0;
function testo(id) {
var btn = document.getElementsByClassName("like-btn");
likes = parseFloat(btn[id].innerHTML);
likes += 1;
btn[id].innerHTML = likes;
}
</script>
<div id="marvelContainer"></div>
I hope it will help you...
Upvotes: 4
Reputation: 24965
// fake out some data for the element generation
var data = { data: {
results: [
{ thumbnail: { path: '/path1', extension: 'jpg', title: 'Element1' } }
,{ thumbnail: { path: '/path2', extension: 'png', title: 'Element2' } }
,{ thumbnail: { path: '/path3', extension: 'gif', title: 'Element3' } }
]
} };
// fake out the container the elements are built to
var marvelContainer = document.querySelector('#container');
var string = "<div class='row'>";
for (var i = 0; i < data.data.results.length; i++) {
var element = data.data.results[i];
string += '<div class="col-md-3" align="center">';
string += "<img src='" + element.thumbnail.path + "/portrait_fantastic." + element.thumbnail.extension + "'/>";
// put a class on the button
// also removed the id and inline onclick
// change the id on the link to a class
// also initialized the data-likes on the link to zero
string += '<button class="btn btn-success likes-button"><i class="fas fa-thumbs-up"></i> | <span class="likes" data-likes="0">0</span></button>';
string += "<h3>" + element.title + "</h3>";
string += "</div>";
if ((i + 1) % 4 == 0) {
string += "</div>";
string += "<div class='row'>";
}
}
marvelContainer.innerHTML = string;
document.querySelectorAll('.likes-button, .likes').forEach(function(likeButton){
likeButton.addEventListener('click', incrementLikes);
});
function incrementLikes (e) {
e.stopPropagation();
// find the inner likes element of the button
var likes = e.target.querySelector('.likes') || e.target;
// increment the likes
var incrementedLikes = parseInt(likes.dataset.likes) + 1;
// update the data attribute for next click, and update the text
likes.dataset.likes = incrementedLikes.toString();
likes.innerText = incrementedLikes;
}
<div id="container">
</div>
Upvotes: 1