Search code examples
javascriptjquerydomeventsjquery-selectors

Javascript EventListener and Element Selector problem


Long story short, I have a JavaScript selector issue.

I have a loop that creates several elements, which each have the same button and a different input value. Clicking a button needs to increase the associated input value by 1, and change aspect (toggle between +1 and -1).

My problem is that clicking on one button changes the aspect of all of them, and increases the value of the last input value instead of it's associated one.

I've tried using [i] with the selector, as well as getElementsByNames instead and many more.

Doesn't seem easy to explain clearly, this might help : https://codepen.io/enukeron/pen/qBaZNbb

Thanks for any help you can give.

HTML :

     <div class="photoGrid">  </div>

Javascipt:

const PhotographeID= 82; 
var jsonFile =  {
        "media": [
    { "photographerId": 82, "likes": 82, },
    { "photographerId": 82, "likes": 62, }
]}
  
const photoLikes= document.getElementById ('photoLikes');
var photoGrid  = document.getElementsByClassName('photoGrid')[0];
var heart=  document.getElementById('heart');
var imageCard  = document.getElementsByClassName('imageCard')[0];

function findId(jsonFile, idToLookFor) {
var media = jsonFile.media;
for (var i = 0; i < media.length; i++) {
if (media[i].photographerId == idToLookFor) {
          
// Creating Dom Elements
 var imageCard = document.createElement('div');
 imageCard.classList.add('imageCard');
 photoGrid.appendChild(imageCard);
                
 var photoInfos = document.createElement('div');
 photoInfos.classList.add('photoInfos');
 imageCard.appendChild(photoInfos);   
                       
 var photoLikes = document.createElement('input');
 photoLikes.classList.add('photoLikes');
 photoLikes.setAttribute("type", "number");
 photoLikes.setAttribute("value", media[i].likes);
 photoLikes.readOnly = true;
 photoInfos.appendChild(photoLikes);        
          
 var heart = document.createElement('span');
 heart.classList.add('heart');
  heart.classList.add(i);
 photoInfos.appendChild(heart);   
          
  var faHeart= document.createElement('i');
  faHeart.classList.add('fa');
  faHeart.classList.add('fa-heart-o');
  faHeart.setAttribute("aria-hidden", "true" );
  faHeart.setAttribute("id", "faHeart");
  heart.appendChild(faHeart);
  
  
// like button functions 
var heartI= document.getElementsByClassName(i);
  
heart.addEventListener('click', (event) => {
if( heart.classList.contains("liked")){
$(".heart").html('<i class="fa fa-heart-o" aria-hidden="true"></i>');
heart.classList.remove("liked");
      
 /*Removes 1 like */
 var value = parseInt(photoLikes.value, 10);
 value = isNaN(value) ? 0 : value;
 value--;
 photoLikes.value = value;  
    }
  
  else{
      $(".heart").html('<i class="fa fa-heart" aria-hidden="true"></i>');
      heart.classList.add("liked");
    
    /*adds 1 like */
var value = parseInt(photoLikes.value, 10);
value = isNaN(value) ? 0 : value;
value++;
photoLikes.value = value; 
    }
  });
; } } }
findId(jsonFile, PhotographeID);

Solution

  • Soooo, I got every thing working: https://codepen.io/enukeron/pen/qBaZNbb?editors=1010

    1. As pointed out by @kaiLehmann the counting problem was due to misusage of Var instead of Const.
    2. The aspect of the buttons changing together was due to the usage of :

    $(".heart").html('<i class="fa fa-heart" aria-hidden="true"></i>');

    instead of heart.innerHTML='<i class="fa fa-heart" aria-hidden="true"></i>';

    I don't know exactly why though, if anyone could explain the difference, expect that one is plain JS and the other Jquery, that would be great!