Looking for assistance with arranging and managing several containers, buttons, and modals?

My goal is to create a grid of photos that, when hovered over, display a button that can be clicked to open a modal. I initially got one photo to work with this functionality, but as I added more photos and buttons, I encountered an issue where the first button no longer opens the modal.

Below is the code snippet I have been working with:

</style>
</head>
<body>

<!-- Photo Grid -->
<div class="row"> 
  <div class="column">

<!-- The Modal -->
<div id="myModal1" class="modal">

  <!-- Modal content -->
  <div class="modal-content">
    <span class="close">&times;</span>
    <h3>Modal Title 1</h3>
    <p>Modal Text 1
</p>
  </div>
</div>

<div class="container">
  <img src="https://previews.dropbox.com/p/thumb/ABFh1yeARivImN6pNH7kuatn60gVuTBKQO9dbkUPSa2nQQWvlgOMt4GIkI5ZlWvHDV1jhXJQ1JqmPPSRwqdwDZ360SPlxnHG7as4GypQWPvCGa0_IiZ8MY-dxF3qQ3azldvGF3P3pFUVOe5oi0pL4cTQiLbj4wqyX7f-SSYaVwD88sU8B-avSdROijI0_3zOecUEfMl9Hrx3uWviDREGperqRhJ7-YaB1VM-LRPh5ESKN92YeEdpM41tIIUL-CAbzcffQYNncc-XUi8TMpOdLL2lvH_s6W1kH70H4PuEt8b0fn5I6oAg8ami7_6GJSK4nPUYxWbrbqiAgrmv2U-7aYeWhtkiRf0l8JDGoP9BVblqcg/p.jpeg?fv_content=true&size_mode=5" alt="Fiona Garufi" style="width:100%">
  <button1 id="myBtn1" class="btn">Button Text 1</button>
  </div>

<!-- The Modal 2-->
<div id="myModal2" class="modal">

  <!-- Modal content 2-->
  <div class="modal-content">
    <span class="close">&times;</span>
    <h3>Modal Title 2</h3>
    <p>Modal Text 2
</p>
  </div>
  
</div>
<div class="container">
  <img src="https://previews.dropbox.com/p/thumb/ABFh1yeARivImN6pNH7kuatn60gVuTBKQO9dbkUPSa2nQQWvlgOMt4GIkI5ZlWvHDV1jhXJQ1JqmPPSRwqdwDZ360SPlxnHG7as4GypQWPvCGa0_IiZ8MY-dxF3qQ3azldvGF3P3pFUVOe5oi0pL4cTQiLbj4wqyX7f-SSYaVwD88sU8B-avSdROijI0_3zOecUEfMl9Hrx3uWviDREGperqRhJ7-YaB1VM-LRPh5ESKN92YeEdpM41tIIUL-CAbzcffQYNncc-XUi8TMpOdLL2lvH_s6W1kH70H4PuEt8b0fn5I6oAg8ami7_6GJSK4nPUYxWbrbqiAgrmv2U-7aYeWhtkiRf0l8JDGoP9BVblqcg/p.jpeg?fv_content=true&size_mode=5" alt="Fiona Garufi" style="width:100%">
  <button1 id="myBtn2" class="btn">Button Text 2</button>

</div>
</div>
</div>

<script>  
// Get the first modal
var modal = document.getElementById("myModal1");

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

// Get the second modal
var modal = document.getElementById("myModal2");

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

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

// When the user clicks 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>

</body>
</html>
<html>
<head>
<style>

.row {
  display: -ms-flexbox; /* IE10 */
  display: flex;
  -ms-flex-wrap: wrap; /* IE10 */
  flex-wrap: wrap;
  padding: 0 4px;
}

/* Create four equal columns that sits next to each other */
.column {
  -ms-flex: 25%; /* IE10 */
  flex: 25%;
  max-width: 25%;
  padding: 0 4px;
}

.column img {
  margin-top: 8px;
  vertical-align: middle;
  width: 100%;
}

/* Responsive layout - makes a two column-layout instead of four columns */
@media screen and (max-width: 800px) {
  .column {
    -ms-flex: 50%;
    flex: 50%;
    max-width: 50%;
  }
}

/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
  .column {
    -ms-flex: 100%;
    flex: 100%;
    max-width: 100%;
  }
}
/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  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 */
.modal-content {
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

/* The Close Button */
.close {
  color: #673589;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}
.container {
  position: relative;
  width: 100%;
  max-width: 400px;
  transition: .4s ease;
}

.container img {
  width: 100%;
  height: auto;
  opacity: 1;
}

.btn {
  position: absolute;
  top: 70%;
  left: 50%;
  transition: .4s ease;
  transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  background-color: rgba(235,235,235,.5);
  opacity: 0;
  color: #351B47;
  font-size: 20px;
  font-family: "Raleway";
  padding: 16px 30px;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  text-align: center;
  id: "myBtn";
}

.container:hover .btn{

  opacity: 1;
}
.container:hover {
    opacity: .75;
}

  opacity: 1;
}

Answer №1

When using the ID in your JavaScript, you're only binding the modal once in the DOM. Consider changing it to use the class name instead, along with improving your CSS for better styling.

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

// All page modals
var modals = document.querySelectorAll('.modal');

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

// When the user clicks the button, open the modal
for (var i = 0; i < btn.length; i++) {
 btn[i].onclick = function(e) {
    e.preventDefault();
    modal = document.querySelector(e.target.getAttribute("href"));
    modal.style.display = "block";
 }
}

// When the user clicks on <span> (x), close the modal
for (var i = 0; i < spans.length; i++) {
 spans[i].onclick = function() {
    for (var index in modals) {
      if (typeof modals[index].style !== 'undefined') modals[index].style.display = "none";    
    }
 }
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target.classList.contains('modal')) {
     for (var index in modals) {
      if (typeof modals[index].style !== 'undefined') modals[index].style.display = "none";    
     }
    }
}
.row {
  display: -ms-flexbox; /* IE10 */
  display: flex;
  -ms-flex-wrap: wrap; /* IE10 */
  flex-wrap: wrap;
  padding: 0 4px;
}

/* Create four equal columns that sit next to each other */
.column {
  -ms-flex: 25%; /* IE10 */
  flex: 25%;
  max-width: 25%;
  padding: 0 4px;
}

.column img {
  margin-top: 8px;
  vertical-align: middle;
  width: 100%;
}

/* Responsive layout - makes a two-column layout instead of four columns */
@media screen and (max-width: 800px) {
  .column {
    -ms-flex: 50%;
    flex: 50%;
    max-width: 50%;
  }
}

/* Responsive layout - stacks the two columns on top of each other instead of next to each other */
@media screen and (max-width: 600px) {
  .column {
    -ms-flex: 100%;
    flex: 100%;
    max-width: 100%;
  }
}
/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  padding-top: 100px; /* Location of the box */
  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 */
.modal-content {
  background-color: #fefefe;
  margin: auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
}

/* The Close Button */
.close {
  color: #673589;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: #000;
  text-decoration: none;
  cursor: pointer;
}
.container {
  position: relative;
  width: 100%;
  max-width: 400px;
  transition: .4s ease;
}

.container img {
  width: 100%;
  height: auto;
  opacity: 1;
}

.btn {
  position: absolute;
  top: 70%;
  left: 50%;
  transition: .4s ease;
  transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  background-color: rgba(235,235,235,.5);
  opacity: 0;
  color: #351B47;
  font-size: 20px;
  font-family: "Raleway";
  padding: 16px 30px;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  text-align: center;
  id: "myBtn";
}

.container:hover .btn{

  opacity: 1;
}
.container:hover {
    opacity: .75;
}

  opacity: 1;
}
<html>
<head>

</head>
<body>

<!-- Photo Grid -->
<div class="row"> 
  <div class="column">

<!-- The Modal -->
<div id="myModal1" class="modal">

  <!-- Modal content -->
  <div class="modal-content">
    <span class="close">&times;</span>
    <h3>Modal Title 1</h3>
    <p>Modal Text 1
</p>
  </div>
</div>

<div class="container">
  <img src="https://via.placeholder.com/150" alt="Fiona Garufi" style="width:100%">
  <button href="#myModal1" id="myBtn1" class="btn">Button Text 1</button>
  </div>

<!-- The Modal 2-->
<div id="myModal2" class="modal">

  <!-- Modal content 2-->
  <div class="modal-content">
    <span class="close">&times;</span>
    <h3>Modal Title 2</h3>
    <p>Modal Text 2
</p>
  </div>
  
</div>
<div class="container">
  <img src="https://via.placeholder.com/150" alt="Fiona Garufi" style="width:100%">
  <button href="#myModal2" id="myBtn2" class="btn">Button Text 2</button>

</div>
</div>
</div>



</body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unleashing the Power: Crafting Impeccable For Loops

After running the select query in the "get-employee.php" page, I obtained the answer for this page. Then, I returned the data to the previous page (home.php). On this page, I added a for loop in JavaScript before the tag with the class "col-md-3". Within t ...

Steps to make pop-up iframe function on the same page within a react nextjs application

My vanilla Html app has a pop-up feature that functions perfectly. When the button is clicked, the pop-up opens and everything works as expected. However, I am encountering an issue when trying to implement this same functionality in my React, NextJS app. ...

The select2 does not show the selected information

My select2 is not selecting the value when in edit mode. You can view my data here. Upon clicking the edit data button, it should select "settings" as the parent's value, but unfortunately, it's not working. You can see the issue here. Modal Sc ...

Change the text color of the Vuetify button to customize its appearance

Is there a way to change the default active color for button text in a toolbar using CSS? v-btn(:to="item.path" active-class="v-btn--active toolbar-btn-active") {{item.meta.title}} I attempted to override it with this custom class: .toolbar-btn-active { ...

Performance problem with 'Point-along-path' d3 visualization

I recently explored a d3 visualization where a point moves along a path, following the code example provided at https://bl.ocks.org/mbostock/1705868. During this movement, I observed that the CPU usage ranges from 7 to 11%. In my current project, there ar ...

Guide to changing the background colors of multiple elements when hovered over by the mouse?

I want to customize my website's search bar by changing the background color when it is hovered over. Currently, the search bar has two main elements: the text box and the submit button. I have successfully programmed the text box element to change to ...

What is causing the div to not update until the for loop is completed?

I have an HTML page where I am trying to update a div while a for loop is running. However, the div does not update until after the loop finishes. Why is this happening? <!DOCTYPE html> <html> <body> ...

Tips for centering content in the middle of a line

How can I center align 3 buttons on a line using CSS and HTML? This is what I have tried so far: 1/ CSS : .center-buttons { display: flex; justify-content: center; } .button { margin: 0 10px; } 2/ HTML: <div class="row"> <di ...

Manipulating Width in CSS

I am facing a challenge with the HTML code below where an automated software inserts the initial CSS style g2f0 <div class="linelevel row"> <div class="g2f0 col-sm-6 form-group"> <label for="name">Name</label> < ...

Eliminate the empty gap preceding the slideshow

I have a slideshow and aside content in HTML. My goal is to eliminate the space below the slideshow so that the aside content can be positioned right next to the end of the slideshow. Unfortunately, I am unsure how to remove this space without disrupting ...

What is the best way to create a reliable and distinct identifier in React while using server-side rendering (

Currently, I am utilizing SSR within Next.js. My goal is to create a unique ID within a component in order to use it as an attribute for a DOM element's id. Since this component might be utilized multiple times on a single page, the ID needs to be dis ...

Having trouble accessing dynamically generated elements using Selenium

I've been attempting to change the router's SSIDs using a Selenium script, but I'm encountering difficulty accessing any JS elements generated by the router page. I've tried various Expected Conditions and methods without success. Here ...

Tips for detecting successful file downloads from the client side using Mean/AngularJS

I have developed a chat application with the capability to send files through chat windows. I am now looking to automatically delete files from the server once they have been successfully downloaded by clients. My technology stack includes MEAN. rou ...

Having trouble verifying the selection option in Angular 6

I've been trying to implement Select option validation in Angular 6, but neither Aria-required nor required seem to be effective. The requirement is for it to display a message or show a RED border similar to HTML forms. Here's the HTML snippet ...

The precision of the css function in jQuery

Possible Duplicate: jQuery and setting margin using jQuery In the HTML snippet below, I have set margins for a paragraph element to center it: <p style="margin-left:auto; margin-right:auto; width:200px;">Hello</p> After that, I attempted ...

Creating layered images with CSS Grid

Visit this link for more details I've been attempting to create an overlap effect with 3 photos using CSS Grid. My desired outcome looks like this: Click here to see the desired result I followed tutorials that demonstrate the same method, but unfo ...

Stop users from repeating an action

We are encountering challenges with users repeating a specific action, even though we have measures in place to prevent it. Here is an overview of our current approach: Client side: The button becomes disabled after one click. Server side: We use a key h ...

Embarking on the journey of launching an Angular application on AWS CloudFront

I have a Laravel PHP application that functions as an API accessed by an Angular single-page app. Currently, the Angular app is situated within the public folder, but I aim to separate it so I can deploy it through Amazon CloudFront. I came across this ar ...

Using form submission to implement reCAPTCHA v3 in g-recaptcha

Is the Recaptcha API causing trouble? I have the key on both the submit button and the form tag, but it's only sending the sitekey without generating tokens. Any suggestions are welcome. You can either use the key in the form tag: <form method=&qu ...

What is the best way to extend the final column of a table across the entire width?

Here's the code I'm working with: .frm-find-people table td:nth-child(1) { padding: 5px 15px; width: 100px } .frm-find-people table td:nth-child(2) { border: 1px solid red; } <form class="frm-find-people"> <table> ...