Flowbite modals not opening again after using built in `show()` & `hide()` functions

379 Views Asked by At

I'm using Flowbite modals to show sign up & sign in forms to the user. At the bottom of each of these modals is a button to switch to the other, e.g. "Not a member? Sign up." or "Already have an account? Sign in."

sign in modal sign up modal

These buttons trigger an onclick event to the function toggleSignInSignUpModals() shown in full below:

function toggleSignInSignUpModals(e) {
  // Hard coded these here for ease of understanding. //
  var currentModalName = "authentication-modal";
  var otherModalName = "sign-in-modal";
  /////////////////////////////////////////////////////
  var currentModalElem = document.getElementById(currentModalName);
  var otherModalElem = document.getElementById(otherModalName);

  const options = {
    placement: 'center',
    backdrop: 'dynamic',
    backdropClasses:
        'bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-40',
    closable: !0,
    onHide: function() {},
    onShow: function() {},
    onToggle: function() {}
  };

  var currentModalObj = new Modal(currentModalElem, options);
  currentModalObj.hide();

  var otherModalObj = new Modal(otherModalElem, options);
  otherModalObj.show();
}

In this function I'm using the built in Flowbite functions hide() & show() to switch between the 2 modals. Docs on these here.

This function works as expected when switching between the 2 modals. However, the modals both cease to operate after you've toggled between them and closed them (shown below):

Note: It's worth mentioning at this point that the modals work perfectly when using them outside of this context (not using my custom function).

For reference, here is the Flowbite javascript being used.

  • The hide() function can be seen on line 2191 link to line
  • The show() function can be seen on line 2189 link to line
  • And I think all the modal stuff starts on line 2106 link to line

The main things I've tried:

  • I tried to instantiate the modals outside of the onclick function, to avoid them being freshly created every time a user toggles between the 2 modals. This resulted in the modals opening a second time successfully but then subsequently not closing properly (the modal overlay not being removed).

  • I have a hunch this is something to do with how Flowbite creates and destroys Modal objects, and maybe I need to call additional methods besides just hide() & show(). So I've tried:

    • setting isHidden = true when hiding and isHidden = false when showing.
    • calling destroy() on the modal we're hiding.
    • calling destroyAndRemoveInstance() on the modal we're hiding.
    • calling removeInstance() on the modal we're hiding.
    • calling toggle() on both modals instead of hide() & show().
  • I also suspected this was to do with event listeners not being reset correctly using just hide() and show(), but looking into both of those functions shows that _removeModalCloseEventListeners() and _setupModalCloseEventListeners() are both being called.


TLDR; How do I get these modals functioning properly? :) Thank you in advance.

1

There are 1 best solutions below

0
On BEST ANSWER

I found a solution to this (with a little help from the founder of Flowbite, thank you sir!).

In the toggleSignInSignUpModals() function: I was creating new Modal objects in addition to the ones already present on the page. This was causing the show() and hide() functions to be called twice for each Modal instance.

More specifically:

  • On exiting the modals, neither instance had an eventListenerInstance, meaning no way for it to be opened again by the user.
  • On exiting the modals, the last modal on screen before exiting was set to isHidden = false, further causing this line to fail within the function _destroyBackdropEl().

Essentially, the modal states were all jacked up due to calling everything twice on each modal.

Here's my (working) code now:

function toggleSignInSignUpModals(e) {
  var currentModalName = "some-name";
  var otherModalName = "some-other-name";

  var currentModalObj = FlowbiteInstances.getInstance('Modal', currentModalName);
  var otherModalObj = FlowbiteInstances.getInstance('Modal', otherModalName);

  currentModalObj.hide();
  otherModalObj.show();
}

Instead of creating new Modal instances, this finds the ones already on the page and handles them directly.

Again, thanks to Zoltán Szőgyényi for the help on this one!