Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

A R
A R
12,834 Points

Event handler firing too many times

I'm trying to get the modals to pop up for the related cards, but each time all the event handlers are firing so the last person is the one that shows up on the page. I'm not sure the route to get only the currently clicked one to show up. I've player around a bit and done some research, but no luck, so I figured I'd reach out. I think it has something to do with their all being attached to $('card'), but I'm not sure how to get the click event to fire on just the clicked card.

//Variables and No-Script-Warning Cardd
const $gallery = $("#gallery");
const $cardNoJs = $('#card-no-js');
const usersAPI = 'https://randomuser.me/api/?results=12';
$cardNoJs.hide();

//function to iterate through array and create cards. 
function createUserCards(data){
    $.each(data, function(index, item){
        appendCard(index, item);
    })
}

//function to generate html and append cards to the gallery DIV
function appendCard(index, item){
     $gallery.append(`<div class="card">\
    <div class="card-img-container">\
    <img class="card-img" src="${item.picture.large}" alt="profile picture">\
    </div>\
    <div class="card-info-container">\
        <h3 id="name" class="card-name cap">${item.name.first} ${item.name.last}</h3>\
        <p class="card-text">${item.email}</p>\
        <p class="card-text cap">${item.location.city}</p>\
    </div>\
</div>`)
$('.card').on('click', $('.card'), function(e){
    console.log($(this));
    createModal(item)
    });
};

function createModal(item){
   $modal = $('body').append(`<div class="modal-container">
    <div class="modal">
        <button type="button" id="modal-close-btn" class="modal-close-btn"><strong>X</strong></button>
        <div class="modal-info-container">
            <img class="modal-img" src="${item.picture.large}" alt="profile picture">
            <h3 id="name" class="modal-name cap">${item.name.first} ${item.name.last}</h3>
            <p class="modal-text">${item.email}</p>
            <p class="modal-text cap">${item.location.city}</p>
            <hr>
            <p class="modal-text">${item.phone}</p>
            <p class="modal-text">${item.location.street.number} ${item.location.street.name} ${item.location.city} ${item.location.state} ${item.location.postcode}</p>
            <p class="modal-text">Age: ${item.dob.age}</p>
        </div>
    </div>

    // IMPORTANT: Below is only for exceeds tasks 
    <div class="modal-btn-container">
        <button type="button" id="modal-prev" class="modal-prev btn">Prev</button>
        <button type="button" id="modal-next" class="modal-next btn">Next</button>
    </div>
</div>`
)
$('#modal-close-button').on('click', function(event){
    console.log('clicked');
    $target = event.target
    $target.hide();
    });
};

//event handler for modal window popups

//AJAX request as outlined in the Random User API. getJSON could also work here
$.ajax({
    url: 'https://randomuser.me/api/?results=12',
    dataType: 'json',
    success: function(data) {
      createUserCards(data.results);
    }
  });

2 Answers

Steven Parker
Steven Parker
231,154 Points

The issue can't easily be replicated without the rest of the code (HTML, CSS) or a link to a snapshot. But on first glance, this looks odd:

$('.card').on('click', $('.card'), function(e){

If I'm interpreting it correctly, the jQuery documenation says this 3-argument version of .on takes a selector string as the 2nd argument, but a jQuery object is being passed here. Perhaps that's causing some anomalous behavior?

Did you possibly intend to use the typical 2-argument version here instead?

A R
A R
12,834 Points

I ended up naming the $card variable. It was selecting all the items with a .card class before, now it just selects the one. I had tried the two-argument version but since it was looking for the class, all the cards were getting a modal window on click.

//creates modal passing in information from clicked card $card.on('click', function(e){ createModal(index, item) }); //appends newly created card and click handler $gallery.append($card);