Why can't I copy and past my code to create a 2nd modal box?

Hi I’m using a template from W3Schools to create modal box. I’d actually like to create dozens of them for a list of proverbs on my webpage. I got the first one to work, but I can’t get a second to work. Here’s the HTML from the first one:

<div class="proverbs"> <div>A (g)attë mbrèšarolë facë i (g)attarièddë cëcatë <button id="myBtn">Open</button> <div id="myModal" class="modal"> <div class="modal-content"> <span class="close">&times;</span> <p>a atːə mˌbɾɪʃəˈɾolə fat͡ʃ i ˈatːaɾiˌɛdːə t͡ʃə katʰ</p> <p>La gatta frettolosa fa i gattini ciechi.</p> <p>The hasty cat makes blind kittens.</p> </div> </div> </div>

Here’s the CSS:

/* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ } /* Modal Content/Box */ .modal-content { background-color: #fefefe; margin: 15% auto; /* 15% from the top and centered */ padding: 20px; border: 1px solid #888; width: 80%; /* Could be more or less, depending on screen size */ } /* The Close Button */ .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; }

Here’s the javascript:

console.log('Hello world!'); <!--Get the modal--> <script> var modal = document.getElementById("myModal"); // Get the button that opens the modal var btn = document.getElementByID("myBtn"); // Get the <span> element that closes the modal var span = document.getElementsByClassName("close")[0]; // When the user clicks on the button, open the modal 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"; } } </script>

I read another forum post that suggested the problem could be the var btn = document.getElementByID("myBtn"); line because IDs are always unique and it wouldn’t create a 2nd modal box. I don’t really understand why I wouldn’t be able to copy and past the HTML over and over again and just type new content into each box. But if this is the problem, I’m not sure how to fix it. Any suggestions? Thanks in advance.

Yes, the reason is .getElementByID can only give you one element, which is the first element that has that id.

You could try to use the modal class instead of the id, and put a loops to do the stuff you want for each element in the class.
And, in the the window.onclick event listener function, the == should be !=,
since you want that to occur only if something that is not modal is clicked on.

If you want one button to make all modals appear, you could do:

// Get the button that opens all the modals
var btn = document.getElementByID("myBtn");

// When the user clicks on the button, open all modals
btn.onclick = function() {
	// a way to set up loop through all elements with class "modal"
	var modals = document.getElementsByClassName("modal");
	// loop through each element in the collection, call each one "modal"
	for (var modal of modals) {
		// make element appear
		modal.style.display = "block";
	}
}

// a way to set up loop through all elements with class "modal"
var modals = document.getElementsByClassName("modal");

for (var modal of modals) {  
    // loop sets modal to be each element of class modal

	// Get the <span> element that closes the modal
	// by getting the child or descendent element of modal that has the class "close"
	var span = modal.querySelector(".close");

	// 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) {
	var target = event.target;
	
	// get collection of all elements with class "modal"
	var modals = document.getElementsByClassName("modal");
	
	/* if neither it nor a parent of it has class "modal" or id "myBtn"
	   then make modal elements disappear one by one, using a loop
	*/
	if (!target.closest(".modal, #myBtn")) {
		for (let modal of modals) {
			// make the element disappear
			modal.style.display = "none";
		}
	}
}

But, if you want to have a button for each modal, (that closes only that modal) and that button is always immediately before the element with class modal, you could do:

// a way to set up loop through all elements with class "modal"
var modals = document.getElementsByClassName("modal");

for (var modal of modals) {  
    // loop sets modal to be each element of class modal
	
	// btn is element just before modal (with same parent)
	var btn = modal.PreviousElementSibling;
	
	// When the user clicks on the button, open the modal
	btn.onclick = function() {
		modal.style.display = "block";
	}
	
	// Get the <span> element that closes the modal
	// by getting the child or descendent element of modal that has the class "close"
	var span = modal.querySelector(".close");
	
	// 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) {
	var target = event.target;
	
	// get collection of all elements with class "modal"
	var modals = document.getElementsByClassName("modal");
	
	/* if element with modal class is not it or a parent, and not myBtn
	   then make modal elements disappear one by one, using a loop
	*/
	if (!target.closest(".modal, #myBtn")) {
		for (let modal of modals) {
			// make the element disappear
			modal.style.display = "none";
		}
	}
}

Although the code might be shorter with if you use one of the JavaScript libraries, like JQuery, I guess.