Rotate magnific-popup gallery array to start with 'clicked item' [jQuery]

40 Views Asked by At

I have an isotope layout with combined filters. The filtered content should be displayed in a magnific-popup gallery.

Therefore I update the var galleryItems after the site is loaded and every time after layoutComplete is fired. I have two separate functions for this.

To make the gallery start with the clicked image I need a function that rotates the order of galleryItems accordingly. To do this, I first determine the index of the clicked image and then reorder the array using slice and concat. The function is executed before the popup is opened.

I have problems with the rotate-array-function. The array is not rotated. The error may already lie in recognizing the index of the clicked image. So the popup-gallery is working fine, also only the filtered items are showed. But it alway starts with the first item.

jQuery(document).ready(function ($) {
  var $container = $('#jobs');

  // Initialize Isotope with Packery layout mode
  $container.isotope({
    itemSelector: '.element-item',
    stamp: '.stamp',
    percentPosition: true,
    packery: {
      columnWidth: '.grid-sizer' // Change this to match your job item selector
    }
  });
  })

  // Script to ensure that only the filtered content is shown in the gallery -> on 'document ready'
  $(document).ready (function ($) {
    var filteredItems = $container.data('isotope').filteredItems;
    var galleryItems = [];
  
    filteredItems.forEach(function (item) {
      var $item = $(item.element);
      var src = $item.find('a').attr('href');
      galleryItems.push({ src: src });
    });
  
    // Print gallery items to the console
    console.log('galleryItems contains:', galleryItems);
  
    // Update Magnific Popup gallery
    $('.grid a').magnificPopup('destroy');
    $('.grid a').magnificPopup({
      type: 'image',
      gallery: {
        enabled: true
      },
      callbacks: {
        beforeOpen: function() { // Execute function before opening the gallery
          rotateArray();
        },
      },
      items: galleryItems
    });
  });

  // Store filter for each group (Isotope)
  var filters = {};

  $('.button-group').on('click', 'button', function () {
    var $this = $(this);
    var $buttonGroup = $this.parents('.button-group');
    var filterGroup = $buttonGroup.attr('data-filter-group');
    filters[filterGroup] = $this.attr('data-filter');
    var filterValue = concatValues(filters);
    $container.isotope({ filter: filterValue });
  });

  // Flatten object by concatenating values
  function concatValues(obj) {
    var value = '';
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        value += obj[prop];
      }
    }
    return value;
  }
  
  $container.on( 'layoutComplete',
  function() {
    console.log( 'Isotope layout completed!');
  });

// Script to ensure that only the filtered content is shown in the gallery -> on 'layoutComplete'
$container.on('layoutComplete', function () {
  var filteredItems = $container.data('isotope').filteredItems;
  var galleryItems = [];

  filteredItems.forEach(function (item) {
    var $item = $(item.element);
    var src = $item.find('a').attr('href');
    galleryItems.push({ src: src });
  });

  // Print gallery items to the console
  console.log('galleryItems contains:', galleryItems);

  // Update Magnific Popup gallery
  $('.grid a').magnificPopup('destroy');
  $('.grid a').magnificPopup({
    type: 'image',
    gallery: {
      enabled: true
      },
    callbacks: {
      beforeOpen: function() { // Execute function before opening the gallery
        beforeOpenFunction();
      },
    },
    items: galleryItems,
  });
});

// Magnific Popup Gallery
jQuery(document).ready(function () {
  $('.grid').magnificPopup({
    items: galleryItems,
    delegate: 'a',
    type: 'image',
    tLoading: 'Loading image #%curr%...',
    mainClass: 'mfp-img-mobile',
    gallery: {
      enabled: true,
      navigateByImgClick: true,
      preload: [0, 1] // Will preload 0 - before the current, and 1 after the current image
    },
    image: {
      tError: '<a href="%url%">The image #%curr%</a> could not be loaded.',
      titleSrc: function (item) {
        return item.el.attr('title') + '<small>by Maximilian Bächli</small>';
      }
    }
  });
});

This is the function rotateArrayto rotate the array, it is called using beforeOpen:

// Function to rotate 'galleryItems' according to the clicked image
function beforeOpenFunction() {
  var filteredItems = $container.data('isotope').filteredItems;
  var galleryItems = [];

  // Find the index of the clicked item
  var clickedItemIndex = -1; // Initialize with an invalid index
  var $clickedItem = $('.grid a.clicked'); // Adjust the selector based on your needs

  filteredItems.forEach(function (item, index) {
    var $item = $(item.element);
    var src = $item.find('a').attr('href');
    galleryItems.push({ src: src });

    // Check if the current item is the clicked item
    if ($item.is($clickedItem)) {
      clickedItemIndex = index;
    }
  });

  // Reorder the galleryItems array starting from the clicked item
  if (clickedItemIndex !== -1) {
    galleryItems = galleryItems.slice(clickedItemIndex).concat(galleryItems.slice(0, clickedItemIndex));
  }

  console.log('galleryItems contains:', galleryItems);
}

the html code

<div id="jobs" class="grid" style="position: relative; height: 452.797px;">
    <div class="grid-sizer"></div>
        <div class="element-item width1 image architekturzentrum-st-gallen" style="position: absolute; left: 0%; top: 0px;"><!-- adds the filter classes to the div -->
            <div class="card-content-wrapper">
                <a href="http://wordpress.test/wp-content/uploads/2023/08/21_fs_image_planbild.jpg">
                    <img src="http://wordpress.test/wp-content/uploads/2023/08/21_fs_image_planbild-724x1024.jpg" alt="">
                        <p>21_fs_image_planbild.jpg</p>   
                </a>
            </div>
        </div>
        <div class="element-item width2 axo hofhaus-im-westfeld" style="position: absolute; left: 11.1111%; top: 0px;"><!-- adds the filter classes to the div -->
            <div class="card-content-wrapper">
                <a href="http://wordpress.test/wp-content/uploads/2023/08/20_fs_axo_apartment-scaled.jpg">
                    <img src="http://wordpress.test/wp-content/uploads/2023/08/20_fs_axo_apartment-1024x724.jpg" alt="">
                        <p>20_fs_axo_apartment-scaled.jpg</p>   
                </a>
            </div>
        </div>
        <div class="element-item width1 image architekturzentrum-st-gallen" style="position: absolute; left: 33.3333%; top: 0px;"><!-- adds the filter classes to the div -->
            <div class="card-content-wrapper">
                <a href="http://wordpress.test/wp-content/uploads/2023/08/21_fs_image_rendering_plaza.jpg">
                    <img src="http://wordpress.test/wp-content/uploads/2023/08/21_fs_image_rendering_plaza-1024x739.jpg" alt="">
                        <p>21_fs_image_rendering_plaza.jpg</p>   
                </a>
            </div>
        </div>
0

There are 0 best solutions below