Multiple Image Change on Click

Hi there,

I am currently trying to change my image source when clicking on the image, until the last image is shown.

In the page template, I defined these variables:

$mn = 0;
$first = $page->images()->nth($mn);

(I somehow tried to increase the $mn variable on click, but didn’t succeed)

this is the image I try to change:

<image id="first" src="<?= $first ->url() ?>"onclick="change_image()">

And I am using this script.

<script type='text/javascript'> function change_image { document.getElementById('first').setAttribute('src','<?= $first->next() ->url() ?>' ); </script> }

So this only helps me change the image to next listed one (of course), but at the moment I have no idea how to go further.

Welcome to the community :slight_smile:

What you need is an array of all the images that you can step through with the click event… something like this in your template.

<?php

// Empty array for our images
$images = [];

// Get the urls and wrap each one in single qoutes
foreach ($page->images() as $img) {
  $images[] = "'". $img->url() . "'";
}

// Make the comma seperated list that javascript can read
$images = implode(', ', $images)

?>

<script>

function ImageCollection(images) {
  this.images = images;
  this.i = 0;
  this.next = function(img) {
    this.i++;
    if (this.i == images.length) this.i = 0;
    img.src = images[this.i];
  };
}

// Use the list of images created above
var imgSet = new ImageCollection([<?= $images ?>]);

</script>


<img src='<?= $page->images()->first()->url() ?>' onclick="imgSet.next(this)">

You say you want it to stop on the last image, however I would argue that that is a poor user experience, since you would need to reload the page and cycle through again to see a picture you went past again. The code above cycles through infinitly.

1 Like

Amazing, thank you so much for the help! :parrot:

Something else should happen when all the images are shown, but for now your loop is great!

No worries. You can make the code above safer by wraping the whole thing in hasImages(). It is good practice to check things exist before trying to use them.

<?php if($page->hasImages()) :

  // Empty array for our images
  $images = [];

  // Get the urls and wrap each one in single qoutes
  foreach ($page->images() as $img) {
    $images[] = "'". $img->url() . "'";
  }

  // Make the comma seperated list that javascript can read
  $images = implode(', ', $images)

?>

<script>

function ImageCollection(images) {
  this.images = images;
  this.i = 0;
  this.next = function(img) {
    this.i++;
    if (this.i == images.length) this.i = 0;
    img.src = images[this.i];
  };
}

// Use the list of images created above
var imgSet = new ImageCollection([<?= $images ?>]);

</script>


<img src='<?= $page->images()->first()->url() ?>' onclick="imgSet.next(this)">

<?php endif ?>
1 Like

Good hint, need to do things like that in literally every line of my code but tried to procrastinate till now :upside_down_face: