0

I'm using a Bootstrap theme and I wanted the image gallery on the theme's image display page to load via AJAX. Photos come as JSON with AJAX but I couldn't get them to show on the page.

The gallery related part of this theme from the original JS file:

var productGallery = function () {
                    var gallery = document.querySelectorAll('.product-gallery');
                    if (gallery.length) {
                        var _loop8 = function _loop8(i) {
                            var thumbnails = gallery[i].querySelectorAll('.product-gallery-thumblist-item'),
                                previews = gallery[i].querySelectorAll('.product-gallery-preview-item');
                            for (var n = 0; n < thumbnails.length; n++) {
                                thumbnails[n].addEventListener('click', changePreview);
                            } // Changer preview function
                            function changePreview(e) {
                                e.preventDefault();
                                for (var _i3 = 0; _i3 < thumbnails.length; _i3++) {
                                    previews[_i3].classList.remove('active');
                                    thumbnails[_i3].classList.remove('active');
                                }
                                this.classList.add('active');
                                gallery[i].querySelector(this.getAttribute('href')).classList.add('active');
                            }
                        };
                        for (var i = 0; i < gallery.length; i++) {
                            _loop8(i);
                        }
                    }
                }();

Data from JSON file with Ajax:

some AJAX code..
if (slidePhotos.photos) {
    for (let x= 0; x< slidePhotos.photos.length; x++) {
        document.getElementById('gallery_photos_div').innerHTML += '<div class="product-gallery-preview-item" id="' + x+ '"><img src="' + slidePhotos.photos[x].url + '" alt=""></div>';

       document.getElementById('gallery_thumbs_div').innerHTML += '<a class="product-gallery-thumblist-item" href="#' + x+ '"><img src="' + slidePhotos.photos[x].url + '"></a>';
    }
}

The HTML Code is generated but unfortunately the images do not change when I click on it.

Sample JSON:

[
   {
   "url":"https://example.com/image1.jpg",
   "url":"https://example.com/image2.jpg"
   }
]

Can you tell me where I made a mistake?

1 Answers1

0

I see a couple of problems here:

  • It looks like the code that you're using to populate your slideshow with new images from that JSON file appends a div.product-gallery-preview-item to your slideshow container, but doesn't append a corresponding .product-gallery-thumblist-item. In your productGallery function, your click handler is being bound to the latter, not the former. You'll want to make sure those target thumbnail elements are added as well as the preview ones.
  • Presumably, your productGallery function is fired when the page/DOM is first loaded to initialize the slideshow. The click event handlers that control the functionality of your slideshow are bound only to the elements that are present when the function runs. If you're not running this function repeatedly when appending content via AJAX (I hope you're not, as this would bind duplicate event handlers to the elements already in the slideshow), you'll need to ensure that your new elements are primed to respond to click in the same way that your existing ones are. You have a couple of options here:
    • Refactor productGallery so that it can be invoked repeatedly with the same slideshow, e.g: adding a :not(.slideshow-processed) to the the end of your .product-gallery-thumblist-item and .product-gallery-preview-item query selectors, and then adding the slideshow-processed class to these elements after binding your event handlers so they won't be processed again during subsequent invocations of productGallery.
    • Refactor productGallery to use event delegation (where a parent element listens for an event that occurs on one of its child elements). This would allow you to bind your event handler to the .product-gallery container just once, and have it fire for any preview/thumbnail pair that gets appended to the slideshow, without having to re-invoke productGallery. You can read more about event delegation at https://javascript.info/event-delegation.

Hopefully this points you in the right direction. Happy coding!

Aaron
  • 5,137
  • 1
  • 18
  • 20