Micromodal icon indicating copy to clipboard operation
Micromodal copied to clipboard

Destroying instances

Open rctneil opened this issue 4 years ago • 9 comments

Hi,

I've just added this to a local project i'm working on. It's great but I have a grid of items, on which some of them have a Micro Modal set up. These work perfectly but when I use Infinite Scroll to append more grid items to the bottom, Micro Modal does not work on those items which require it that have been appended.

What is the best way of destroying all the Micro Modal instances and recreating them once the new items have been added to the grid?

Thanks, Neil

rctneil avatar Apr 10 '20 16:04 rctneil

@rctneil Thanks for reporting, we don't have a way of doing this yet. However, that is something we want to solve for our next release.

Meanwhile, if you are using the init method, them try calling Micromodal.init() after the items are appened.

ghosh avatar Apr 11 '20 08:04 ghosh

Thanks, I did try that after appending items but it didn’t seem to make any difference and didn’t initialise the new modals.

rctneil avatar Apr 11 '20 09:04 rctneil

Noted. Will work on a fix.

ghosh avatar Apr 11 '20 09:04 ghosh

@ghosh , maybe something like this? https://github.com/banthagroup/fslightbox/blob/c3470d0445a360e2bee47b4962d0b570a03fe48d/src/index.js

A part from that everything is literally perfect, great job 🧡

Edodums avatar Apr 15 '20 15:04 Edodums

@Edodums Yes, something like the refresh mothod.

ghosh avatar Apr 16 '20 07:04 ghosh

I had this same issue. The below is what worked for me.

function refreshModals() {
    // Use whatever selector you're using for MicroModal triggers.
    const modalTrigger = 'data-micromodal-trigger';

    // Get all triggers. 
    const modalTriggers = document.querySelectorAll( `[${modalTrigger}]` );

    modalTriggers.forEach( trigger => {
        // Get the attribute to save.
        const triggerElement = trigger.getAttribute( modalTrigger );
        
        // Remove the attribute briefly to clear memory/existing modals.
        trigger.removeAttribute( modalTrigger );

        // Immediately add it back.
        trigger.setAttribute( modalTrigger, triggerElement );

        // Re-initialize.
        MicroModal.init();
    } );
}

// Call whenever you need (AJAX calls, infinite scrolling, etc).
refreshModals();

I have not tested thoroughly, but it has no side effects in my use case. This seems to be enough to flush the MicroModal memory and help a new initialization succeed. @ghosh If the above is at all reckless, let me know. Hope this helps.

joshangehr avatar Apr 24 '20 04:04 joshangehr

Ran into the need for a .destroy() method but in a different use case. We have multiple potential triggers but only want to show the modal once to a user on a page.

My solution was a little different in this case. Since MicroModal checks to be sure that the modal exists, I just remove the modal from the DOM when it's closed.

That said, it would be much nicer to have an upstream option to destroy a modal instance and/or make a way to only trigger the open event once.

const modalId = 'my-modal';
// remove the modal from the DOM
const modalClose = function() {
	const modal = document.getElementById(modalId);
	modal.parentNode.removeChild(modal);
}

MicroModal.init({
	onClose: modalClose,
});

mrwweb avatar Jan 20 '21 00:01 mrwweb

+1

hasenov avatar Jan 02 '22 08:01 hasenov

@mrwweb

Another way to show only once would be to have a variable that you set as false, like modalShown = false, then check if that is false before triggering the modal, then with the onShow event change the variable to true. Next time the modal tries to show, it will check the variable and this time it will fail the condition, so the modal is only shown once.

wplit avatar Feb 21 '22 22:02 wplit