Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HTMX/Flowbite.js] initFlowbite() causes an open modal to display twice #820

Open
samld opened this issue Feb 28, 2024 · 1 comment
Open

Comments

@samld
Copy link

samld commented Feb 28, 2024

The issue

I'm currently building an application using Blazor SSR and HTMX. Within one of my pages, I have a delete button that triggers the replacement of a placeholder div and then opens the parent modal.

<Modal Id="delete-confirm-modal" Title="Delete">
        <div id="delete-ingredient-confirm" class="p⁻4 flex items-center justify-center">
                <!-- placeholder to be replaced -->
        </div>
</Modal>

(Modal is a simple Blazor component that encapsulates the functionality)

The div #delete-confirm-modal works perfectly. The X to dismiss the modal works, as it is not part of the content loaded via HTMX. But in my dynamic content, there's a button that allows me to answer: « No, cancel », which triggers the modal to close, and it doesn't fire, given it has been loaded following the initialization. Alright, I say, let's reinitialize flowbite whenever I load new content:

htmx.onLoad(function (content) {
    initFlowbite()
})

Thing is, now a second instance of my modal appears on top of the first one. And weirdly enough, the backdrop disappears until I click on it again.

Before dismissing
image
After dimissing
image

Notice the backdrop difference?

Here's the (beautified) inspect when I have the layered components:

<div id="delete-ingredient-confirm-modal" tabindex="-1" class="overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full flex" aria-modal="true" role="dialog">
   <div class="relative p-4 w-full max-w-md max-h-full">
      <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
         <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
            <h2 class="text-lg font-semibold text-gray-900 dark:text-white">Supprimer</h2>
            <button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-toggle="delete-ingredient-confirm-modal" id="delete-ingredient-confirm-modal-close">
               <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
                  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"></path>
               </svg>
               <span class="sr-only">Fermer la modale</span>
            </button>
         </div>
         <div id="delete-ingredient-confirm" class="p⁻4 flex items-center justify-center">
            <div class="flex flex-col mb-4 gap-4 p-4">
               <p>
                  Êtes-vous sûr(e) de vouloir supprimer cet ingrédient&nbsp;?
               </p>
               <div class="flex justify-center items-center space-x-4"><button data-modal-toggle="delete-ingredient-confirm-modal" type="button" class="py-2 px-3 text-sm font-medium text-gray-500 bg-white rounded-lg border border-gray-200 hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-primary-300 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">
                  No, cancel
                  </button>
                  <button type="submit" class="py-2 px-3 text-sm font-medium text-center text-white bg-red-600 rounded-lg hover:bg-red-700 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-500 dark:hover:bg-red-600 dark:focus:ring-red-900">
                  Yes, I'm sure
                  </button>
               </div>
            </div>
         </div>
      </div>
   </div>
</div>

Strangely enough, my inspect only shows the modal being rendered once. If I omit (re-)initializing flowbite on HTMX load events, this strange behaviour doesn't happen.

EDIT: Inspecting the instances

Here we can see that, despite the modal being shown, it thinks it's hidden.
image
image

Here we can see that once the duplicated modal is closed, it shows the proper state.
image
image

Potential Fix/Feature Request

A good way to solve this type of issues would be to have a proper re-initialization function that omits instances that are already initialized. Like so:

htmx.onLoad(function (content) {
    reinitFlowbite() // or initUnitializedFlowbite(), or initFlowbite({uninitializedOnly: true})
})

Or to simply ignore already initialized instances with the base function.

@samld samld changed the title [HTMX/Flowbite.js] initModals() causes an open modal to display twice [HTMX/Flowbite.js] initFlowbite() causes an open modal to display twice Feb 28, 2024
@samld
Copy link
Author

samld commented Feb 29, 2024

I have opened a pull request (#824) to address this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant