Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Magnific Popup: Update class on change of image.

I am using the Magnific Popup plugin for some gallery functionality, however, I am using some custom code in PHP to determine whether it is a landscape or portrait image, I then went to pass that as a class each time the gallery image is changed between clicks so that they will be sized appropriately. I am stumped, nothing I try seems to work:

Using data-layout, $imageLayout is either landscape or portrait, this part works.

            <a href="<?php echo $full_array[0]; ?>" itemprop="contentUrl" data-effect="mfp-zoom-in" data-layout="<?php echo $imageLayout; ?>">
                <div class="intrinsic intrinsic--4-3">
                    <?php if(get_sub_field('custom_thumbnail')): ?>
                    <img src="<?php the_sub_field('custom_thumbnail'); ?>" itemprop="thumbnail" alt="">
                    <?php else: ?>
                    <img src="<?php echo $default_array[0]; ?>" itemprop="thumbnail" alt="">
                    <?php endif; ?>
                </div>
            </a>

And here is the JS

$('.gallery').magnificPopup({
        type: 'image',
        delegate: 'a',
        removalDelay: 500,
        mainClass: 'mfp-with-fade',
        image: {
            markup:
                    '<div class="mfp-figure">' +
                    '<div class="mfp-logo"><img src="' + wnm_custom.template_url + '/img/ryan-c-jones-logo.png" alt=""></div>' +
                    '<div class="mfp-img"></div>' +
                    '<div class="mfp-bottom-bar mfp-prevent-close">' +
                    '<span title="%title%" class="mfp-arrow mfp-arrow-left"><img src="' + wnm_custom.template_url + '/img/left-arrow.svg" alt="Previous" class="mfp-prevent-close"></span>' +
                    '<div class="mfp-caption-wrap">' +
                    '<div class="mfp-title"></div>' +
                    '<div class="mfp-counter"></div>' +
                    '</div>' +
                    '<span title="%title%" class="mfp-arrow mfp-arrow-right"><img src="' + wnm_custom.template_url + '/img/right-arrow.svg" alt="Next" class="mfp-prevent-close"></span>' +
                    '</div>' +
                    '</div>',
            titleSrc: function(item) {
                return item.el.parent().find('figcaption').html();
            }
        },
        gallery: {
            enabled: true
        },
        closeOnContentClick: true,
        midClick: true,
        callbacks: {
            beforeOpen: function() {
                // just a hack that adds mfp-anim class to markup
                this.st.image.markup = this.st.image.markup.replace('mfp-figure', 'mfp-figure mfp-with-anim');
                this.st.mainClass += ' ' + this.st.el.attr('data-effect');
            },
            change: function() {
                if (this.isOpen) {
                    this.wrap.addClass('mfp-open');
                }
                var img = this.content.find('img');
                img.css('max-height', parseFloat(img.css('max-height')) * 0.85);

                alert(this.st.mainClass);
            },
            resize: function() {
                var img = this.content.find('img');
                img.css('max-height', parseFloat(img.css('max-height')) * 0.85);
            }
        }
    });

    var magnificPopup = $.magnificPopup.instance;

    $('body').on('click', '.mfp-arrow-left', function() {
        magnificPopup.prev();
    });

    $('body').on('click', '.mfp-arrow-right', function() {
        magnificPopup.next();
    });

I tried making

this.st.mainClass += ' ' + this.st.el.attr('data-effect');

into

this.st.mainClass += ' ' + this.st.el.attr('data-effect') + ' ' + this.st.el.attr('data-layout');

But that doesn't work when the image is changed, it only works if you click on images individually, but not if you scroll through as a gallery.

Any ideas?

1 Answer

Hi mikes02,

If I understand the problem, each thumbnail will indicate either a portrait or landscape orientation. You want to then assign one of those classes to the magnific wrap element based on which image is currently showing and it would come from the corresponding thumbnail.

Let me know if I've misunderstood anything.

Looking at the documentation, I think you're going to want to do this in the change callback because that one will be called each time the content is updated. beforeOpen only happens once when the popup first opens.

Similarly, this.st.el only targets the item that was clicked on to open the popup. After you start navigating with the arrows it's no longer going to be useful.

I noticed that there's an index property available in the API portion of the docs. It gives you the index of the item currently displayed. You could then use this as an index into the thumbnail links to get the proper orientation and add it to the wrap element.

Before the magnific code:

// loop through the thumbnails and save the orientation in an array for quicker access later
var orientations = $('.gallery a').map(function() {
  return $(this).attr('data-layout');
}).get();
// orientations ex. ["landscape", "portrait", "portrait"]

Then in the change callback:

 change: function() {
  // existing code omitted

  // get the orientation using the index of the current item
  var orientation = orientations[this.index];

  // add that class to the wrap element
  this.wrap.addClass(orientation);

  // ternary operation - if current orientation is landscape then remove the portrait class, otherwise remove the landscape class
  orientation == "landscape" ? this.wrap.removeClass("portrait") : this.wrap.removeClass("landscape");
}

Let me know if you have any questions about this or if I have misunderstood the problem.

That looks very promising and much cleaner than what I was using. Let me give that a try!