Search code examples
jqueryajaxmagnific-popup

Magnific Popup - Loading content from external page and put it in the slideshow


Here is what i want to do. I'm attempting to make the galleries I have on my site more portable so i can generate a link to my projects page and then have Magnific Popup display the contents from that page into the slider.

I'd like to work like it would if all of the elements were on this page maybe hidden inline, but i can't load these items inline, i have to fetch them from the external page.

Let's look at some code, first off, I have a text link that links to the projects page:

<a href="http://domain.com/projects/my-project-template/" class="external-media">View Project</a>

If you visit the project template, you'll see the carousel of work samples. But if a link with class .external-media is clicked, jquery should take over and load items from this page into the magnific popup.

I have the data outputting in html format and I also tried json too. The html structure is something like the following:

<div id="gallery">
<a href="photo1.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal"><img src="/thumbnail1.jpg" alt="" class="standard-image"></a>
<a href="photo2.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal"><img src="/thumbnail2.jpg" alt="" class="standard-image"></a>
<a href="photo3.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal"><img src="/thumbnail3.jpg" alt="" class="standard-image"></a>
<a href="photo4.jpg" title="" class="gallery-item" data-effect="mfp-move-horizontal"><img src="/thumbnail4.jpg" alt="" class="standard-image"></a>
</div>

Then my javascript looks like this, i was trying to use the ajax type.

jQuery('.external-media').magnificPopup({
  type: 'ajax',
  modal: false,
  gallery: {
    enabled: true,
    navigateByImgClick: true,
    preload: [0,1]
  },
  image: {
    tError: '<a href="%url%">The image #%curr%</a> could not be loaded.',
    titleSrc: function(item) {
    return item.el.attr('title');
    }
  },
  callbacks: {
    parseAjax: function(mfpResponse) {
    mfpResponse.data = jQuery(mfpResponse.data).find('#gallery');
    console.log('Ajax content loaded:', mfpResponse);
  },
  ajaxContentAdded: function() {                            
    $('#gallery').magnificPopup({
      type: 'image',
      delegate: 'a',
      gallery: {
                enabled: true,
                tPrev: 'previous',
                tNext: 'next',
                tCounter: '%curr% of %total%'
      },
      image: {
       verticalFit: true,
       titleSrc: function (item) {
       return item.el.attr('title') + ' &middot; <a class="image-source-link" href="' + item.src + '" target="_blank"><i class="fa fa-file-image-o"></i> open original</a>';
          }
        },
    });
    console.log(this.content);
    }
  }
});

Right now what happens when i click the text link, it displays all 4 images stacked on top of each in the lightbox. I want to display one at a time in the slideshow with the left, right arrows.

Basically, have it look exactly like how it does if all of the elements are on the same page.

Anyone got any tips how i can load images from an external source and populate the lightbox in a slideshow?

===

I'm exploring some other options now since some of you offered some ideas. Here is what I got, but it doesnt seem to work. I think it is a half solution right now. I have a click function that grabs the contents from the permalink page and loads it into a div on the current page template. I can see the items in the content div after i click the link but i can't get the lightbox to open. Clearly i am doing something wrong here.

$('.external-media').click(function( event ) {

    event.preventDefault();

    var href = jQuery(this).attr('href') + ' #gallery';
    var items = [];

    $.ajax({
            url: href,
            type:'GET',
            success: function(data){
                         $('#content').html(
                            $(data).find('.slide').each(function() {
                             items.push({
                                 src: $(this)
                                });
                         })
                    );
            }
    });

    $.magnificPopup.open({
        type: 'inline',
        gallery: {
                enabled: true,
                tPrev: 'previous',
                tNext: 'next',
                tCounter: '%curr% of %total%'
        }
    }); // close mpopup

}); // close click

Two things i am seeing when i click this function. I see the items appear in the div, they do not load in the lightbox. However, clicking one of the items does load that item into the lightbox. So that is a problem because i want the lightbox to open right when the user clicks the link.

The other issue i see when i click the link i am getting a javascript error.

Uncaught TypeError: Cannot read property 'parsed' of undefined

I'm going to experiment some more, but if you guys have some other thought i am open to hear any and all options, suggestions.


Solution

  • This answer isn't 100% but it is close enough for me to post this as answer. The remaining issues are just front-end stuff.

    With this code I'm able to get the items from the other page to load in the carousel, however, the html markup that wraps around the items is not correct. I'm still working on that part. I think this is pretty close that i wanted to share it so others can see how to accomplish a similar thing if they want too.

    This is how you would load items from a different page on your site to appear in a lightbox. It works in the same way as if the items were inline.

    First, you need a link that goes to your page that has your items on it and you need to apply the "external-media" class.

    <a href="{permalink}" class="external-media">External Media Link</a>
    <div id="content"></div>
    

    Then, I'm using ajax to grab these items from a div with id="gallery". I'm loading the content into a div with id="content" on the page where the link is.

    Here is the jquery click function and the ajax call. I did need to add the items portion in this part to get the items into the lightbox. (Thanks Emm for that and I will award my bounty to you for that part.)

    $('.external-media').click(function( event ) {
    
        event.preventDefault();
    
        var href = jQuery(this).attr('href') + ' #gallery';
        var items = [];
    
        $.ajax({
                url: href,
                type:'GET',
                success: function(data){
                  $('#content').html(
                    $(data).find('.slide').each(function() {
                      items.push({
                        src: $(this)
                      });
                    })
                  );
                },
                complete: function() {
                  $.magnificPopup.open({
                    items: items,
                    type: 'inline',
                    image: {
                     markup: '<div class="mfp-figure">'+
                     '<div class="mfp-close"></div>'+
                     '<div class="mfp-img"></div>'+
                     '<div class="mfp-bottom-bar">'+
                     '<div class="mfp-title"></div>'+
                     '<div class="mfp-counter"></div>'+
                     '</div>'+
                     '</div>',
                    },
                    gallery: { enabled: true }
                }); // close mpopup
             }
        });    
    });
    

    The last bit is to modify the html code that wraps the items in the lightbox to make it responsive and match the other lightboxes that i have on other parts of the site.