dimsemenov / Magnific-Popup

Light and responsive lightbox script with focus on performance.
http://dimsemenov.com/plugins/magnific-popup/
MIT License
11.39k stars 3.49k forks source link

Unable to update content #955

Open poa8a opened 7 years ago

poa8a commented 7 years ago

I use Magnific to show images on a web page, and have a feature to let the user update the image caption/title. I have the caption in a data-image-description attribute on the img element. When the user updated the caption, it's updated in the database and then I update mfp.currItem as well as mfp.items array. See code below. But even if I do all these things the "old" caption is still shown, and that's even if I close the popup and re-open it. The underlying DOM structure is updated with the new caption though. I have also tried many other possible solutions to "reload" the content but to no luck:

So, if I have an image with caption "123" and I (as an end user) update it to "456", the data attribute on the img element is updated, and also the mfp.currItem.el and mfp.items[index] are updated.

The only way I can get Magnific to show the new "456" caption is to reload the page and then open Magnific again. Is there a way to achieve this through the API? If not, can someone guide me to where I should start looking in the Magnific code to do this?

Please help, I really need this to work.

The elements I use to create the Magnific:

<div class="hypo-img-container" data-image-id="152">
   <a href="/images/user/3/full/152.jpg" data-image-id="152">
       <img class="hypo-image-thumbnail " src="/images/user/3/152.jpg" data-image-description="123" data-image-license="ddddddddd" data-image-thumbnail="true" data-image-originalsize="">
   </a>
   <span class="glyphicon glyphicon-remove user-image-remove-chapter" data-image-id="152" data-target-id="43" data-toggle="tooltip" title="Ta bort från avsnitt."></span>
</div>

I create the Magnific with this code:

        $.fn.off('click.magnificpopup');
        $.fn.removeData('magnificPopup');

        $("#currentSection").magnificPopup({
            delegate: ".hypo-img-container a",
            type: 'image',
            gallery: {
                enabled: true,
                navigateByImgClick: true,
                preload: [1, 2, 3, 4]
            },
            focus: '',
            image: {
                markup: '<div class="mfp-figure">' +
                    '<div class="hypo-image-toolbar-container js-hypo-right-menu-container"><div class="main-menu-container js-main-menu-container fix-position"><nav id="mainMenu" class="right-menu"><ul><li><a id="buttonShowImageMetadata" class="hypo-image-toolbar-button"><i class="hypo-toolbar-fa fa fa-info fa-lg"></i></a></li><li><a id="buttonEditImageMetadata" class="hypo-image-toolbar-button"><i class="hypo-toolbar-fa fa fa-pencil fa-lg"></i></a></li></ul></nav></div><div class="clearfix" style="height: 100%;width: 100%;">&nbsp;</div></div>' +
                    '<div class="mfp-close"></div>' +
                    '<div class="hypo-image-metadata-container hidden">' +
                    '<h3>Metadata till bild id <span id="userImageMetadataId"></span></h3>' +
                    '<label>Bildbeskrivning:</label>' +
                    '<input class="form-control hypo-image-description" type="text" value="min bildbeskrivning"></input>' +
                    '<label>Licens:</label>' +
                    '<input class="form-control hypo-image-license" type="text" value="licens till bilden"></input>' +
                    '<div class="hypo-image-popover-button-container">' +
                    '<button class="btn hypo-blue-btn-color popover-confirm hypo-image-popover-button">Spara</button>' +
                    '<button class="btn btn-default popover-close hypo-image-popover-button">Avbryt</button>' +
                    '</div>' +
                    '<div class="clearfix"></div>' +

                    '<div id="userImageMetadataError" class="row hidden">' +
                    '<span class="user-image-error-message-prefix">Skrotnisse!</span>Något har gått fel på servern. Kontakta oss gärna för att rapportera felet.' +
                    '<div><label>Felmeddelande: </label><span id="userImageMetadataErrorMessage"></span></div>' +
                    '<div class="free-anteckning-confirm-buttons col-sm-12 hypo-no-padding">' +
                    '<a href="mailto:info@hypocampus.se" class="hypo-error-alert-email btn btn-default btn-lg"><span class="glyphicon glyphicon-envelope"></span> Kontakta oss</a>' +
                    '<button id="closeErrorButton" type="button" class="btn btn-default btn-lg">Stäng</button>' +
                    '</div>' +
                    '</div>' +

                    '</div>' +
                    '<div class="mfp-img"></div>' +
                    '<div class="mfp-bottom-bar">' +
                    '<div class="mfp-title"></div>' +
                    '<div class="mfp-counter"></div>' +
                    '</div>' +
                    '</div>',
                titleSrc: function(item) {
                    console.log("poa: item:", item);
                    var myimg = $(item.el).find("img");
                    if (myimg) {
                        var description = myimg.data('image-description');
                        var license = myimg.data('image-license');
                        console.log("poa: ", description, license);

                        if (!description) {
                            description = '';
                        }

                        if (!license) {
                            license = '';
                        }

                        var descriptionDiv = $("<div class='image-caption-description'></div>");
                        var licenseDiv = $("<small class='image-caption-license'></small>");
                        $(descriptionDiv).html(description);
                        $(licenseDiv).html(license);
                        var imgText = $(descriptionDiv).prop("outerHTML") + $(licenseDiv).prop("outerHTML");
                        console.log("poa: title:", imgText, $(descriptionDiv).html());
                        return imgText;
                    }
                }
            },
            callbacks: {
                open: function() {
                    var mfp = this;

                    $("#buttonEditImageMetadata").off().on("click", function(e) {
                        var button = $(this);
                        console.log("poa: ", $(this));

                        if ($(this).hasClass("metadata-showing")) {
                            $(mfp.content).find(".hypo-image-metadata-container").addClass("hidden");
                            $(button).removeClass("metadata-showing");
                            mfp.metadata = false;
                            return;
                        }
                        $(button).addClass("metadata-showing");
                        mfp.metadata = true;
                        me.setMetadata(mfp);

                        $(mfp.content).find(".popover-close").off().on("click", function() {
                            $(mfp.content).find(".hypo-image-metadata-container").addClass("hidden");
                            $(button).removeClass("metadata-showing");
                            mfp.metadata = false;
                            return;
                        });

                        $(mfp.content).find(".popover-confirm").off().on("click", function() {
                            var imageId = $(this).data("image-id");
                            me.updateImageMetadata(imageId, mfp);
                            return;
                        });
                    });
                },
                imageLoadComplete: function() {
                    console.log('Image loaded', $(this.currItem.el).find("img").data("image-description"));
                    if (this.metadata) {
                        me.setMetadata(this);
                    }
                }
            }
        });

When the caption has been updated in the database, I've tried to update mfp with this code:

$(mfp.currItem.el).find("img").attr("data-image-description", description);
                    $(mfp.currItem.el).find("img").attr("data-image-license", license);
// this will print the new updated caption in console:
                    console.log("poa: ", $(mfp.currItem), mfp.items[mfp.index]);
                    mfp.items[mfp.index] = mfp.currItem;
// also tried this:
//                    mfp.items[mfp.index].el = mfp.currItem.el;
// tried with and without this:
                    mfp.updateItemHTML();
// this shouldn't be necessary if updateItemHTML() works, right?
                    $(".mfp-title").find(".image-caption-description").html(description);
                    $(".mfp-title").find(".image-caption-license").html(license);

// also tried to close, detach and re-init the mfp:
                    mfp.close();
                    $(mfp.contentContainer).remove();
                    //                    setTimeout(function() {
                    //                        // Unbind any existing click binds on magnific.
                    //                        $.fn.off('click.magnificpopup');
                    //                        $.fn.removeData('magnificPopup');
                    //
// this function is the one I use to create the mfp in the first place, I tried it here to re-init:
                    //                        me.bindImagesToMagnific("#currentSection", ".hypo-img-container a");
// with and without this:
                    //                        mfp.updateItemHTML();
                    //                        console.log("poa: rebounded");
                    //                    }, 500);
rascboy commented 7 years ago

@poa8a I have a very similar use case and have tried most of what you've tried in your post with no success... Have you had any luck with this since the initialize posting?

jasonhildebrand commented 4 years ago

I also needed to update magnific popup after the content dynamically changed (ajax) on a page.

This approach worked for me:

# set magnific's global instance to null
$.magnificPopup.instance = null;

# now re-create magnific from scratch
('.my-selector').magnificPopup({
   ...options...
});