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

The checkbox appears unchecked, yet the content normally associated with a checked checkbox is still visible

As the title suggests, I am encountering an issue with my code. Here is the snippet: $('#somediv').change(function() { if(this.checked) { $('.leaflet-marker-pane').show(1); } else { $('.leaflet-marker-p ...

Angular: Compilation of SCSS/SASS results in unexpected whitespace issues

I am encountering an issue with whitespace being added to the CSS after compiling a *.scss file in my Angular 7 project. This unwanted whitespace is causing incorrect results in the UI. To replicate the problem, you can visit... ...and copy and paste the ...

The art of sweet redirection with Sweetalert2

I am working on a PHP page where users can input a number in a text field. If the entered number exceeds their available credit, I need to display an error message. Upon clicking the submit button to send the form, the user is directed to makeTransfer.php ...

Tips for adding an image to a single product page without including it in the related products section

I have a WooCommerce website and I successfully inserted an image element on a single product page using a conditional tag. However, the same image is also appearing in related products near the website footer in a loop. I do not want these extra images to ...

Having trouble passing a jQuery variable containing a string value to PHP through the jQuery AJAX function?

Below is the jQuery function code snippet: function processMessage() { if (textValue != "") { messageString='<div class="alert-box round"><p class="text-left">' + username + ':' + textValue + '</p>< ...

Retrieve tag, custom taxonomy, and attachment information using the get_pages function

Currently, I have implemented code that retrieves all pages submitted by the currently logged-in author using the get_pages function. The retrieved result is then passed to Javascript via Ajax. Everything functions as expected, and the correct pages are be ...

Change the location of an html td element with JavaScript

I am currently working on a simple JavaScript car racing game where the cars are represented by HTML table elements. I want to implement functionality where pressing the "e" key moves player one's car and the "d" key moves player two's car. This ...

Mouse hovering over the JS slider activates the sliding functionality, while removing the cursor

Hi there, I'm encountering some issues with the JS clients slider on my website. I need to pause it when the mouse is over and resume when the mouse leaves. I've double-checked the code but for some reason it's still not functioning properl ...

How can the node version be set globally in NVM?

While utilizing Node Version Manager, setting the node version to the latest one in the current directory can be done using nvm use node. But how can you specify a specific version to use? ...

Please enter data into the input fields provided in the text

Below is the code where Google transliteration is used for typing in Indian language in a text field. There are two routes with different page IDs. Initially, the transliteration works fine on the default page. However, when changing routes, an error occur ...

What is the process for applying the source from an object while utilizing video-js?

I've been struggling to use a video player for streaming m3u8 videos. The code below works, but I want to dynamically set the source using an object. <video id="my-video" class="video-js" auto ...

Display the div if the input field is left blank

Is there a way to display the div element with id="showDiv" only if the input field with id="textfield" is empty? <form action=""> <fieldset> <input type="text" id="textfield" value=""> </fieldset> </form> <div id="sh ...

Trouble with retrieving dates in ISO format

My collection stores the date of birth field in ISO format, for example: ISODate("1980-01-01T20:20:19.198Z") However, when I use a date time picker on my HTML page, it displays the date like this: 01/01/1980 Unfortunately, when querying for the date of ...

The issue arises with loading data from the server due to lack of definition of Mongo

I am experiencing a console bug and need assistance. It seems that there is an issue with loading data from the server as I am getting an error stating "Mongo is not defined." C:\Users\Robert\Desktop\FINISH\node_modules\mongod ...

Managing iframes in React using reference methods

Trying to set the content of an iframe within a React component can be a bit tricky. There is a component that contains a handleStatementPrint function which needs to be called when the iframe finishes loading. The goal is to print the loaded iframe conten ...

Merging two arrays by their corresponding IDs and indexes

Within my current project, I am working with two arrays. The first array, arr1, contains a questionID property that I need to use to combine it with arr2 based on the condition where arr1 questionID equals arr2 index. For example, if arr1 questionID is 1, ...

Tips for setting unique click functions for each face of a cube using React Three Fiber

Hey there! I have created a basic Cube component using react three fibre. import {useState,useRef} from 'react'; import { useFrame } from '@react-three/fiber'; const Box = ({props}) =>{ const ref = useRef() const [hove ...

Creating a personalized HTML email template with a TypeScript foreach loop

As I work on developing an app, users will have the opportunity to share product information via email. Each product includes a title, image, description, ingredients, and a list of energy values. Currently, I am able to send an email with all the product ...

Retrieving selections from a group of checkboxes and managing their addition or removal in an array

Currently, I am in the process of creating a form that includes a group of checkboxes. My goal is to be able to capture the value of a specific checkbox when it is clicked and add it to an Array using the useState hook. If the checkbox is unchecked, I wan ...

Display the title of an image beneath the image using CSS

Since upgrading my CMS, I've encountered an issue where the captions of images are not showing below the image for thousands of articles. For example: <img src="123.jpg" alt="Texttext" class="caption" style="disp ...