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

Valerie Laughlin
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Valerie Laughlin
Front End Web Development Techdegree Graduate 16,110 Points

Javascript pop-up modal only works on the first item clicked

Hello! I am currently working on a front-end degree project where I have to grab data from an API and display it through AJAX.

My issue is that I have to display a modal pop-up window with more data everytime a user is clicked.

The modal is only working when I click the button of the first item but is not working on the rest of the 11 items.

I read somewhere that it's best to use "css classes" instead of "IDS" because IDs are supposed to be unique for a DOM element. I have already replaced GetElementbyClassName instead of GetElementbyId and it has not worked for me.

I'll appreciate your input. Thanks.

Here is my project

https://github.com/vlaughlin/Treehouse-Project-10-API

Javascript
//LOAD DOM//

$(document).ready(function () {

 //GET JSON DATA USING AN AJAX HTTP GET REQUEST//

    $.getJSON(
        'https://randomuser.me/api/', //API URL//

        {
            results: 12, // AMOUNT OF EMPLOYEES
            nat: ['us'], // NATIONALITY 
        },


        function displayEmployees(data) {
            var EmployeeHTML = '<ul>';
            $.each(data.results, function (i, employee) {
                //BUILD HTML TO DISPLAY PHOTOS IN PAGE//
                EmployeeHTML += '<li class="employee-list">';

                EmployeeHTML += '<img class="profile-pic" src="' + employee.picture.medium + '">'

                //BUILD HTML TO DISPLAY NAMES IN PAGE//
                EmployeeHTML += '<div class="employee-info">';
                EmployeeHTML += '<span class="employee-name">' + employee.name.first + ' ' + employee.name.last + '</span>' + '<br>'
                //BUILD HTML TO DISPLAY EMAILS IN PAGE//
                EmployeeHTML += '<span class="employee-email">' + employee.email + '</span>' + '<br>'
                //BUILD HTML TO DISPLAY LOCATIONS IN PAGE//
                EmployeeHTML += '<span class="employee-location">' +
                    employee.location.city + '</span>' + '<br>'
                //BUILD HTML TO DISPLAY BUTTONS IN PAGE//

                EmployeeHTML += '<button id ="detailsButton">More Details </button>'

                '</div>'

                //BUILD THE MODAL
                EmployeeHTML += '<div id="employeeModal" class="modal">'
                EmployeeHTML += '<div class="modal-content">'
                EmployeeHTML += '<span class="close">&times;</span>' +
                    '<p>'

                EmployeeHTML += '<img class="profile-pic" src="' + employee.picture.large + '">'
                EmployeeHTML += '<span class="employee-name-modal">' + employee.name.first + ' ' + employee.name.last + '</span>'
                //BUILD HTML TO DISPLAY EMAILS IN PAGE//
                EmployeeHTML += '<span class="employee-email-modal">' + employee.email + '</span>'
                //BUILD HTML TO DISPLAY LOCATIONS IN PAGE//
                EmployeeHTML += '<span class="employee-location-modal">' +
                    employee.location.city + '</span>'
  '</p>'
'</div>'
 '</div>'

});



            EmployeeHTML += '</ul>';
            $('#employee_directory').html(EmployeeHTML);


 // Get the modal


var modal = document.getElementById("employeeModal");

// Get the button that opens the modal
var btn = document.getElementById("detailsButton");

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on the button, open the modal 
for (var i = 0; i < detailsButton.length; i++){
btn.onclick = function() 
    modal.style.display = "block";
}


// When the user clicks on <span> (x), close the modal
span.onclick = function() {
    modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }

}

 }); //GET JSON DATA END

}); //LOAD DOM END  ```

<!DOCTYPE html>

<html>

<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Project 10: Use a Public API to Create a Front End for an Employee Directory</title> <link href="https://fonts.googleapis.com/css?family=Mukta" rel="stylesheet">

<link rel="stylesheet" href="css/stylesheet.css" type="text/css">

<script type="text/javascript" src="js/jquery-3.2.1.min.js"></script>

<script type="text/javascript" src="js/main.js"></script>

</head>

<body>

<h1>AWESOME STARTUP EMPLOYEE DIRECTORY</h1>


<div class="container">
    <ul class="list" id="employee_directory"></ul>



</div>

</body>

</html> ```

1 Answer

Steven Parker
Steven Parker
231,236 Points

You're right that there should be only one element with a specific ID on the page. But just converting and ID to a class is only part of the solution, you still need to re-work the programming to handle multiple elements instead of just one. Using getElementsByClassName and then taking the 0 element using an index returns only one of the elements (the first one).

You could use a loop to establish handlers on each element, but since you're already using jQuery you could take advantage of jQuery's way of handing multiple items (with a bit of DOM traversal):

  $(".detailsButton").click(e => $(e.target).next().css("display", "block"));   // ALL buttons
  $(".close").click(e => $(e.target).parent().parent().css("display", "none")); // ALL close spans 

Also, you should add this to the end of the "each" loop that builds the employees, to complete the tags it starts:

  EmployeeHTML += "</p></div></div></div></li>";

And you can remove the code that adds start and end "ul" tags, since the entire thing gets inserted into an existing "ul" element.

Valerie Laughlin
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Valerie Laughlin
Front End Web Development Techdegree Graduate 16,110 Points

All of the pop-up windows work now after following your advice. Thank you so much, You are awesome!!!!!! The DOM transversal code did everything it had to do with so little code. :)