Animale38 Animale38 - 6 months ago 8
HTML Question

Back and forward buttons on a modal over an image gallery (to scroll through)?

I have an image gallery that uses CSS and Javascript to open the image in a modal over the gallery based on a tutorial by w3schools.com. I was originally having issues with it pointing to an external image, but, someone on here was able to show me how to fix that. Now, I would like to make forwards and backwards buttons so that the user can move through the gallery without closing out the modal every time. I've managed to get the arrow buttons to appear in the modul (and size and move and appear) how I would like. Unfortunately, I have been unable to get the buttons to change the image and text in the middle. The best I could do has been to get it to stop crashing the modal and at least stay on the same image and text when clicked. Here's my code so far.

<!-- The Modal -->
<div id="myModal" class="modal">
<span class="close">×</span>
<div class="backButton" id="bckBtn"><img src="../gallery_images/buttonPlaceHolder.png" alt="Back" style="width:100%; float:left">
</div>
<img class="modal-content" id="img01">
<div id="caption"></div>
<div class="forwardButton" id="fwdBtn"><img src="../gallery_images/buttonPlaceHolder.png" alt="Forward" style="width:100%; float:right;">
</div>
</div>

<script>
var modal = document.getElementById('myModal');

var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}

var backButton = document.getElementById('bckBtn');
var forwardButton = document.getElementById('fwdBtn');
var images = document.getElementsByTagName('img');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
var i;
for (i = 0; i < images.length; i++) {
images[i].onclick = function(){
modal.style.display = "block";
var src = this.src;
var filename = src.substring(src.lastIndexOf('/')+1);
var filepath = src.substring(0, src.lastIndexOf('/')+1);
modalImg.src = filepath + 'large-' + filename;
modalImg.alt = this.alt;
captionText.innerHTML = this.nextElementSibling.innerHTML;
backButton.onclick = function() {
var filename = src.substring(src.lastIndexOf('/')+1);
var filepath = src.substring(0, src.lastIndexOf('/')+1);
modalImg.src = filepath + 'large-' + filename;
modalImg.alt = this.alt;
captionText.innerHTML = nextElementSibling.innerHTML;
}
forwardButton.onclick = function() {
var filename = src.substring(src.lastIndexOf('/')+1);
var filepath = src.substring(0, src.lastIndexOf('/')+1);
modalImg.src = filepath + 'large-' + filename;
modalImg.alt = this.alt;
captionText.innerHTML = nextElementSibling.innerHTML;
}
}
}

modalImg.onclick = function() {
modal.style.display = "none";
}

</script>


Seems like long and complicated method to creating what I would like, but, I'm new to Javascript (just started today). Any thoughts would be appreciated.

Answer

Your question looks more like "Does anyone here cool enought to code something for me?" isn't it?

Well, I took it as a fun exercice to complete, since Turnip already contributed a lot on your previous question. And I considered it would be sad not to encourage someone on it's first day in Javascript.
But hey! I'm not sure you'll get so much chance in the future!
;)

Now basically, what this code does is to assign an onclick function to all your thumbnails to display the corresponding larger image in your modal. It also "opens" your modal on the first thumbnail click.
This is the part Turnip did.
Notice that these thumbnail images must now have the "GalleryImg" class.
I added this to the Turnip's version to make sure not to include your back and forward buttons in the loop, because they also are images.

For your back and forward buttons, I added a hidden input which I use as a memory slot holding the actual image displayed in the modal.
So notice that the thumbnails all must have an id that is "zero based" : The first thumbnail id is img-0.
Starting from this information, your back and forward buttons can deduct the id number of the image you wish to display depending on which button you click.

Ho... I also anticipated your next question which sure would have been to restart from the first image when the last has been reached and vice-versa.
Try to find which lines are doing the trick! ;)

Here is the code:

<!-- The Modal -->
<div id="myModal" class="modal">
  <span class="close">×</span>
  <div class="backButton" id="bckBtn"><img src="../gallery_images/buttonPlaceHolder.png" alt="Back" style="width:100%; float:left"></div>
  <img class="modal-content" id="img01">
  <div id="caption"></div>
  <div class="forwardButton" id="fwdBtn"><img src="../gallery_images/buttonPlaceHolder.png" alt="Forward" style="width:100%; float:right;"></div>
  <input type="hidden" id="mem">
</div>

<img class="GalleryImg" id="img-0" src="../path/to/image1" alt="alternate text 1"><div>caption text 1</div>
<img class="GalleryImg" id="img-1" src="../path/to/image2" alt="alternate text 2"><div>caption text 2</div>
<img class="GalleryImg" id="img-2" src="../path/to/image3" alt="alternate text 3"><div>caption text 3</div>
<img class="GalleryImg" id="img-3" src="../path/to/image4" alt="alternate text 4"><div>caption text 4</div>
<!-- and so on... -->

<script>
var modal = document.getElementById('myModal');

var span = document.getElementsByClassName("close")[0];
span.onclick = function() { 
    modal.style.display = "none";
}

var backButton = document.getElementById('bckBtn');
var forwardButton = document.getElementById('fwdBtn');
var images = document.getElementsByClassName('GalleryImg');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
var i;
for (i = 0; i < images.length; i++) {
   images[i].onclick = function(){
       modal.style.display = "block";
       var src = this.src;
       var filename = src.substring(src.lastIndexOf('/')+1);
       var filepath = src.substring(0, src.lastIndexOf('/')+1);
       modalImg.src = filepath + 'large-' + filename;
       modalImg.alt = this.alt;
       captionText.innerHTML = this.nextElementSibling.innerHTML;
       document.getElementById("mem").value=this.id;
   }
}

backButton.onclick = function(){
    ImageId = document.getElementById("mem").value.split("-");
    PreviousImage = parseInt(ImageId[1])-1;
    if(PreviousImage<0){PreviousImage=images.length-1;}
    images[PreviousImage].click();
}

forwardButton.onclick = function(){
    ImageId = document.getElementById("mem").value.split("-");
    NextImage = parseInt(ImageId[1])+1;
    if(NextImage>=images.length-1){NextImage=0;}
    images[NextImage].click();
}
</script>


EDIT (2016-05-03)

To "reverse" the ids numbering, as asked in the comments below, to be like this:

<!-- Future images to be added here-->
<img class="GalleryImg" id="img-3" src="../path/to/image1" alt="alternate text 3"><div>caption text 3</div>
<img class="GalleryImg" id="img-2" src="../path/to/image2" alt="alternate text 2"><div>caption text 2</div>
<img class="GalleryImg" id="img-1" src="../path/to/image3" alt="alternate text 1"><div>caption text 1</div>
<img class="GalleryImg" id="img-0" src="../path/to/image4" alt="alternate text 0"><div>caption text 0</div>

A reversed array of the images elements has to be created... Since the id numbers are linked to the position of the target image in an array of elements.
And then, you reverse to logic of the back and forward buttons.

Use this code :

// Create a "reversed" images array
var imagesReversed = [];    
var i = images.length;
while(i--){
    imagesReversed.push(images[i]);
}

// Adds 1 from the actual id to get the target image position in the reversed array.
backButton.onclick = function(){
    ImageId = document.getElementById("mem").value.split("-");
    PreviousImage = parseInt(ImageId[1])+1;
    if(PreviousImage>images.length-1){PreviousImage=0;}
    imagesReversed[PreviousImage].click();
}

// Substracts 1 from the actual id to get the target image position in the reversed array.
forwardButton.onclick = function(){
    ImageId = document.getElementById("mem").value.split("-");
    NextImage = parseInt(ImageId[1])-1;
    if(NextImage<0){NextImage=images.length-1;}
    imagesReversed[NextImage].click();
}
Comments