javascriptmodal-dialogslider

Slideshow with JS modal that opens with both click on image or button


I have an image Slideshow Gallery with a modal built into it using JavaScript.

When the user clicks on the image displayed in the slide the modal opens on that particular image. I also would like to add a button below the slideshow that opens the modal for the displayed image but I don't know how to link it so that it opens on the current slide image.

I tried multiple scripts trying to incorporate the click on button variable into the i loop, and end up just interfering with the scripts ability to open modal thru the image.

Here is the complete slideshow: https://codepen.io/canQuackattack/pen/ogNbOme

let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("demo");
  let captionText = document.getElementById("slide_caption");
  if (n > slides.length) {
    slideIndex = 1
  }
  if (n < 1) {
    slideIndex = slides.length
  }
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";
  }
  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" active", "");
  }
  slides[slideIndex - 1].style.display = "block";
  dots[slideIndex - 1].className += " active";
  captionText.innerHTML = dots[slideIndex - 1].alt;
}

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

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

// Create reference to the modal for all images using a class!
var images = document.getElementsByClassName('myImages');

// Get each image and insert it inside the modal - use its "alt" text as a caption
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");

// Go through all of the images with our custom class
for (var i = 0; i < images.length; i++) {
  var img = images[i];
  // and attach our click listener for this image.
  img.onclick = function(evt) { // click on <img> to run function 
    modal.style.display = "block"; // function will display modal using class 
    modalImg.src = this.src; // var modalImg gets <img> src  
    captionText.innerHTML = this.alt; // var captionText gets <img> alt  
  }
}

// When the user clicks the button, open the modal 
btn.onclick = function(evt) {
  modal.style.display = "block";
}

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

// 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";
  }
}
/* Position the image container (needed to position the left and right arrows) */
.container {
  position: relative;
}

/* Hide the images by default */
.mySlides {
  display: none;
}

/* Add a pointer when hovering over the thumbnail images */
.cursor {
  cursor: pointer;
}

/* Next & previous buttons */
.prev,
.next {
  cursor: pointer;
  position: absolute;
  top: 40%;
  width: auto;
  padding: 16px;
  margin-top: -50px;
  color: white;
  font-weight: bold;
  font-size: 20px;
  border-radius: 0 3px 3px 0;
  user-select: none;
  -webkit-user-select: none;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
  background-color: rgba(0, 0, 0, 0.8);
}

/* Number text (1/3 etc) */
.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* Container for image text */
.caption-container {
  text-align: center;
  background-color: #222;
  padding: 2px 16px;
  color: white;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

/* columns side by side */
.column {
  float: left;
  width: 16.66%;
}

/* Add a transparency effect for thumnbail images */
.demo {
  opacity: 0.6;
}

.active,
.demo:hover {
  opacity: 1;
}

/********** MODAL **********/

/* 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: rgba(219, 219, 219, 0.9);
}

/* Modal Content (image) */
.modal-content {
  margin: auto;
  display: block;
  width: 40%;
  max-width: 40%;
}

/* Caption of Modal Image */
#caption {
  margin: auto;
  display: block;
  width: 80%;
  max-width: 700px;
  text-align: center;
  color: #000;
  ;
  padding: 10px 0;
  height: 150px;
}

/* Add Animation */
.modal-content,
#caption {
  -webkit-animation-name: zoom;
  -webkit-animation-duration: 0.6s;
  animation-name: zoom;
  animation-duration: 0.6s;
}

@-webkit-keyframes zoom {
  from {
    -webkit-transform: scale(0)
  }

  to {
    -webkit-transform: scale(1)
  }
}

@keyframes zoom {
  from {
    transform: scale(0)
  }

  to {
    transform: scale(1)
  }
}

/* The Close Button */
.close {
  position: fixed;
  /* prev absolute */
  top: 25px;
  /* prev 15 */
  right: 75px;
  /* prev 35 */
  color: #646363;
  font-size: 40px;
  font-weight: bold;
  transition: 0.3s;
}

.close:hover,
.close:focus {
  color: #bbb;
  text-decoration: none;
  cursor: pointer;
}

/* 100% Image Width on Smaller Screens */
@media only screen and (max-width: 700px) {
  .modal-content {
    width: 100%;
  }
}
<body>

  <h2 style="text-align:center">Slideshow Gallery</h2>

  <div class="container">
    <div class="mySlides">
      <div class="numbertext">1 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_woods_wide.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">2 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" style="width:100%">
    </div>

    <div class="mySlides">
      <div class="numbertext">3 / 3</div>
      <img class="myImages" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
    </div>


    <a class="prev" onclick="plusSlides(-1)">❮</a>
    <a class="next" onclick="plusSlides(1)">❯</a>

    <div class="caption-container">
      <p id="slide_caption"></p>
    </div>

    <div class="row">
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_woods_wide.jpg" style="width:100%" onclick="currentSlide(1)" alt="The Woods">
      </div>
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" style="width:100%" onclick="currentSlide(2)" alt="Cinque Terre">
      </div>
      <div class="column">
        <img class="demo cursor" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
      </div>

    </div>
  </div>
  <div>
    <button id="myBtn">Open Modal</button>
  </div>

  <!-- The Modal -->
  <div id="myModal" class="modal">
    <span class="close">&times;</span>
    <img id="img01" class="modal-content">
    <div id="caption"></div>
  </div>


Solution

  • You can check the current image with class active and copy it to the modal

    var btn = document.getElementById("myBtn");
    btn.onclick = function() {
      const currentActiveSlide = document.querySelector('.demo.active');
      modalImg.src = currentActiveSlide.src;
      captionText.innerHTML = currentActiveSlide.alt;
      modal.style.display = "block";
    }
    

    Code snippet for demostration:

    let slideIndex = 1;
    showSlides(slideIndex);
    
    function plusSlides(n) {
      showSlides(slideIndex += n);
    }
    
    function currentSlide(n) {
      showSlides(slideIndex = n);
    }
    
    function showSlides(n) {
      let i;
      let slides = document.getElementsByClassName("mySlides");
      let dots = document.getElementsByClassName("demo");
      let captionText = document.getElementById("slide_caption");
      if (n > slides.length) {
        slideIndex = 1
      }
      if (n < 1) {
        slideIndex = slides.length
      }
      for (i = 0; i < slides.length; i++) {
        slides[i].style.display = "none";
      }
      for (i = 0; i < dots.length; i++) {
        dots[i].className = dots[i].className.replace(" active", "");
      }
      slides[slideIndex - 1].style.display = "block";
      dots[slideIndex - 1].className += " active";
      captionText.innerHTML = dots[slideIndex - 1].alt;
    }
    
    // Get the modal
    var modal = document.getElementById("myModal");
    
    var btn = document.getElementById("myBtn"); // Get the button that opens the modal
    
    // Create reference to the modal for all images using a class!
    var images = document.getElementsByClassName('myImages');
    
    // Get each image and insert it inside the modal - use its "alt" text as a caption
    var modalImg = document.getElementById("img01");
    var captionText = document.getElementById("caption");
    
    // Go through all of the images with our custom class
    for (var i = 0; i < images.length; i++) {
      var img = images[i];
      // and attach our click listener for this image.
      img.onclick = function(evt) { // click on <img> to run function 
        modal.style.display = "block"; // function will display modal using class 
        modalImg.src = this.src; // var modalImg gets <img> src  
        captionText.innerHTML = this.alt; // var captionText gets <img> alt  
      }
    }
    
    // When the user clicks the button, open the modal 
    btn.onclick = function() {
      const currentActiveSlide = document.querySelector('.demo.active');
      modalImg.src = currentActiveSlide.src;
      captionText.innerHTML = currentActiveSlide.alt;
      modal.style.display = "block";
    }
    
    // Get the <span> element that closes the modal
    var span = document.getElementsByClassName("close")[0];
    
    // 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";
      }
    }
    /* Position the image container (needed to position the left and right arrows) */
    .container {
      position: relative;
    }
    
    /* Hide the images by default */
    .mySlides {
      display: none;
    }
    
    /* Add a pointer when hovering over the thumbnail images */
    .cursor {
      cursor: pointer;
    }
    
    /* Next & previous buttons */
    .prev,
    .next {
      cursor: pointer;
      position: absolute;
      top: 40%;
      width: auto;
      padding: 16px;
      margin-top: -50px;
      color: white;
      font-weight: bold;
      font-size: 20px;
      border-radius: 0 3px 3px 0;
      user-select: none;
      -webkit-user-select: none;
    }
    
    /* Position the "next button" to the right */
    .next {
      right: 0;
      border-radius: 3px 0 0 3px;
    }
    
    /* On hover, add a black background color with a little bit see-through */
    .prev:hover,
    .next:hover {
      background-color: rgba(0, 0, 0, 0.8);
    }
    
    /* Number text (1/3 etc) */
    .numbertext {
      color: #f2f2f2;
      font-size: 12px;
      padding: 8px 12px;
      position: absolute;
      top: 0;
    }
    
    /* Container for image text */
    .caption-container {
      text-align: center;
      background-color: #222;
      padding: 2px 16px;
      color: white;
    }
    
    .row:after {
      content: "";
      display: table;
      clear: both;
    }
    
    /* columns side by side */
    .column {
      float: left;
      width: 16.66%;
    }
    
    /* Add a transparency effect for thumnbail images */
    .demo {
      opacity: 0.6;
    }
    
    .active,
    .demo:hover {
      opacity: 1;
    }
    
    /********** MODAL **********/
    
    /* 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: rgba(219, 219, 219, 0.9);
    }
    
    /* Modal Content (image) */
    .modal-content {
      margin: auto;
      display: block;
      width: 40%;
      max-width: 40%;
    }
    
    /* Caption of Modal Image */
    #caption {
      margin: auto;
      display: block;
      width: 80%;
      max-width: 700px;
      text-align: center;
      color: #000;
      ;
      padding: 10px 0;
      height: 150px;
    }
    
    /* Add Animation */
    .modal-content,
    #caption {
      -webkit-animation-name: zoom;
      -webkit-animation-duration: 0.6s;
      animation-name: zoom;
      animation-duration: 0.6s;
    }
    
    @-webkit-keyframes zoom {
      from {
        -webkit-transform: scale(0)
      }
    
      to {
        -webkit-transform: scale(1)
      }
    }
    
    @keyframes zoom {
      from {
        transform: scale(0)
      }
    
      to {
        transform: scale(1)
      }
    }
    
    /* The Close Button */
    .close {
      position: fixed;
      /* prev absolute */
      top: 25px;
      /* prev 15 */
      right: 75px;
      /* prev 35 */
      color: #646363;
      font-size: 40px;
      font-weight: bold;
      transition: 0.3s;
    }
    
    .close:hover,
    .close:focus {
      color: #bbb;
      text-decoration: none;
      cursor: pointer;
    }
    
    /* 100% Image Width on Smaller Screens */
    @media only screen and (max-width: 700px) {
      .modal-content {
        width: 100%;
      }
    }
    <body>
    
      <h2 style="text-align:center">Slideshow Gallery</h2>
    
      <div class="container">
        <div class="mySlides">
          <div class="numbertext">1 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_woods_wide.jpg" style="width:100%">
        </div>
    
        <div class="mySlides">
          <div class="numbertext">2 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" style="width:100%">
        </div>
    
        <div class="mySlides">
          <div class="numbertext">3 / 3</div>
          <img class="myImages" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%">
        </div>
    
    
        <a class="prev" onclick="plusSlides(-1)">❮</a>
        <a class="next" onclick="plusSlides(1)">❯</a>
    
        <div class="caption-container">
          <p id="slide_caption"></p>
        </div>
    
        <div class="row">
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_woods_wide.jpg" style="width:100%" onclick="currentSlide(1)" alt="The Woods">
          </div>
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_5terre_wide.jpg" style="width:100%" onclick="currentSlide(2)" alt="Cinque Terre">
          </div>
          <div class="column">
            <img class="demo cursor" src="https://www.w3schools.com/howto/img_mountains_wide.jpg" style="width:100%" onclick="currentSlide(3)" alt="Mountains and fjords">
          </div>
    
        </div>
      </div>
      <div>
        <button id="myBtn">Open Modal</button>
      </div>
    
      <!-- The Modal -->
      <div id="myModal" class="modal">
        <span class="close">&times;</span>
        <img id="img01" class="modal-content">
        <div id="caption"></div>
      </div>