0

I want to stop incrementing the number of individual likes if the photo was liked(clicked) once, and increment the total number of likes for each individual photo liked(clicked)

individual photo likes likesAfterAddition
global photo likes globalNumberOfLikes

For the moment it is increasing every time I click in both individual and global likes, I know it is not the right logic!

What logic can I use please?

//increment likes on click
function incrementLikesOnClick() {
  const heartIcons = Array.from(document.getElementsByClassName('heartIcon')); // multiple heart icons
  heartIcons.forEach((likeIcon, index) => likeIcon.addEventListener('click', () => {

    const individualLikeBox = document.getElementsByClassName('under-photo-info');
    const totalLikesDivBox = document.getElementById("likesBox");
    likeIcon.classList.add('activeRed');

    let likesAfterAddition = likesTable[index] + 1;  // add 1 like to the individual current photo
    likesTable.splice(index, 1, likesAfterAddition); // replace the old value from the Array with the new value

    let sum = likesTable.reduce(function(a, b){return a + b;}); // return the sum of the array
    let globalNumberOfLikes = sum; // the sum of the array

    individualLikeBox[index].innerHTML = `<span'>${likesAfterAddition}</span>`
    totalLikesDivBox.innerHTML = `<div class="Likes">${globalNumberOfLikes}<i class="fas fa-heart"></i></div>`
    console.log(likesTable)
  }))
}

example

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
deveb2020
  • 101
  • 2
  • 9
  • Be careful when adding event listeners in a loop. See [this thread](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). – Phix Feb 05 '21 at 21:53
  • @Phix thank you, i'll check it – deveb2020 Feb 05 '21 at 21:57

3 Answers3

1

instead of using for loop to set event listeners which is not efficient

you can use the feature of bubbling, so when any of dom element is clicked, the event will bubble up of its parent elements sequentially till it reaches the parent dom

//increment likes on click
function incrementLikesOnClick() {
    document.addEventListener("DOMContentLoaded", function(event) {
        // Your code to run since DOM is loaded and ready
        document.addEventListener('click', () => {
            let clicked = event.target;
            
            //element with class heartIcon is clicked and it doesnt have activeRed class
            if(clicked.classList.contains('heartIcon') && !clicked.classList.contains('activeRed')){
                let productContainer = clicked.parentElement.parentElement; // till you reach the product container
                
                const individualLikeBox = productContainer.getElementsByClassName('under-photo-info');
                const totalLikesDivBox = productContainer.getElementById("likesBox");
                clicked.classList.add('activeRed');

                // ..whatever extra logic you want to add
            }
        });
    });
}
0

If the like icon is a button (which I assume it is). U can just add a 'disabled' attribute to it as part of the event handler (for the 'click' eventListener).

'When present, it specifies that the button should be disabled.

A disabled button is unusable and un-clickable.' (source)

yoty66
  • 390
  • 2
  • 12
  • thank you, like icon it is actually an icon , I don't want to be disabled by default but i want to be disabled the second time it is clicked – deveb2020 Feb 05 '21 at 22:04
  • Maybe u should wrap the icon with a button div. This way you could also utilize the onClick attribute . See https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers, https://www.w3schools.com/howto/howto_css_icon_buttons.asp – yoty66 Feb 05 '21 at 22:13
0

I would calculate the total likes based on the presence of an "active" class on each button.

const totalLikesEl = document.querySelector('#total-likes');

const updateTotalLikes = () => {
  totalLikesEl.textContent = document.querySelectorAll('.like.active').length;
};

const toggleLike = (e) => {
  const button = e.currentTarget.classList.toggle('active');
  updateTotalLikes();
};

document.querySelectorAll('.like').forEach(likeBtn => {
  likeBtn.addEventListener('click', toggleLike);
});
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
}

.cards {
  display: flex;
  flex-direction: row-wrap;
  justify-content: center;
}

.card {
  display: flex;
  flex-direction: column;
  padding: 0.25em;
  margin: 0.5em;
  border: thin solid grey;
}

.card-content {
  background: grey;
  width: 6em;
  height: 6em;
}

.card-actions {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  margin-top: 0.5em;
}

.like > .fa-heart {
  color: grey;
}

.like.active > .fa-heart {
  color: red;
}

.example-1 .card-content {
  background: rgb(63,94,251);
  background: radial-gradient(circle, rgba(63,94,251,1) 0%, rgba(252,70,168,1) 100%);
}

.example-2 .card-content {
  background: rgb(251,63,94);
  background: radial-gradient(circle, rgba(251, 63,94,1) 0%, rgba(168,252,70,1) 100%);
}

.example-3 .card-content {
  background: rgb(94,63,251);
  background: radial-gradient(circle, rgba(94,63,251,1) 0%, rgba(70,252,168,1) 100%);
}

.status {
  text-align: center;
  margin-top: 0.5em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" rel="stylesheet"/>
<div class="cards">
  <div class="card example-1">
    <div class="card-content"></div>
    <div class="card-actions">
      <button class="like">
        Like <i class="fas fa-heart"></i>
      </button>
    </div>
  </div>
  <div class="card example-2">
    <div class="card-content"></div>
    <div class="card-actions">
      <button class="like">
        Like <i class="fas fa-heart"></i>
      </button>
    </div>
  </div>
  <div class="card example-3">
    <div class="card-content"></div>
    <div class="card-actions">
      <button class="like">
        Like <i class="fas fa-heart"></i>
      </button>
    </div>
  </div>
</div>
<div class="status">
  <strong>Total Likes:</strong>
  <span id="total-likes">0</span>
</div>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132