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

How to call initModals from JS? #524

Closed
RadekHavelka opened this issue Apr 10, 2023 · 15 comments
Closed

How to call initModals from JS? #524

RadekHavelka opened this issue Apr 10, 2023 · 15 comments
Assignees

Comments

@RadekHavelka
Copy link

In docs you mention

https://flowbite.com/docs/getting-started/introduction/#components

The initFlowbite function sets up all of the init functions for dropdowns, modals, navbars, tooltips and so on to hook onto the data attributes. Alternatively, you can also initialise each component category class separately with initDropdowns or initModals.

but there is no example how to use that in plain JS, not components. I am dynamically adding buttons that needs have tags to toggle modal (that is present in the code already) and need flowbite to re-detect these buttons and make the toggles work. I expect there is a simple function like the one mentioned initModals() that can do that, but I cannot seem to find it anywhere once the flowbite js code is loaded. Maybe its hidden in some namespace?

@AndrMoura
Copy link

I have encountered the same problem, wherein I have a page that contains multiple comments, each with a 'report' button that links to a singular report modal. Whenever I dynamically add new comments (using HTMX), these newly added report buttons do not have a listener to the report modal. Using the original initModals alone does not solve the issue as it also adds event listeners to buttons that already have existing listeners, causing event stacking (and massive performance issues). To address this issue, I have created my own initModals in JavaScript that adds event listeners to new content only. Additionally, I modified the source code to access the original Modal instance (that is created when the page loads), allowing me to tag the new comment's respective report button to the original report modal!

I would like to hear a devs opinion to address this type of issue.

@RadekHavelka
Copy link
Author

as I purchased the PRO version of this code, I'd love to hear some feedback from the developer, because in current situation this is rather useless. Its not only problem of modals, its any case of "data-dropdown-toggle" or any other component bound like that. Bootstrap has this sorted out very nicely and I don't see a reason why this should not be working the same way.

@zoltanszogyenyi
Copy link
Member

Hey @RadekHavelka,

Can you please give me an example of how you're trying to use it?

I'll need a reproduction to be able to provide a patch or feature update for this.

Cheers,
Zoltan

@RadekHavelka
Copy link
Author

I have HTML page that uses flowbite. After it loads, when user does a certain interaction, new HTML code is loaded via javascript fetch, and injected into page. If this code contains any "interactive" flowbite things like dropdowns, modals etc, they are NOT initialised and not working as expected, because (I believe) flowbite initialisation runs only once and I am not aware of any function to reinit it again (see my original post here about missing info in doc).

In bootstrap you would simply call something to do the init the newly added items, create listeners etc.

Would be enough to have such a call available in plain javascript (ie window.flowbite.init() or whatever), without the problems mentioned above (that it adds multiple listeners in case the elements were already initialised).

I suggest to add some data attribute or class to initialised elements and not reinit them again, this might do the magic.

I am aware I can do all the interactivity manually using javascript, but that looses advantage of this framework.

@zoltanszogyenyi
Copy link
Member

zoltanszogyenyi commented Apr 27, 2023

Hey @RadekHavelka,

Thanks for the explanation - this should be an easy fix.

All we need to do is attach the initFlowbite() function to the window object for the general file.

You could technically also import flowbite via WebPacks (ESM or CJS) and then import initFlowbite from 'flowbite' and you could initialise the components programatically at any point in time based on your own codebase.

I'll look into this for sure for a new minor version.

Cheers,
Zoltan

Edit: the init stacking is indeed something we'll have to also work on so we can keep an object of instances for the initialised components and skip them whenever the initFlowbite function is called again.

@RadekHavelka
Copy link
Author

What I used to use in JQuery was that .live(click, ...) that used to work on any matching elements inserted now or in future, that was pretty handy.
https://api.jquery.com/live/
its deprecated now, but might be useful for ideas

@moshegutman
Copy link

I’m pretty sure we need to use the MutationObserver to monitor changes to the DOM. This would solve Blazor compatibility too.

@leandrodesouzadev
Copy link

Is there any updates on this issue?

@malikvogt
Copy link

I have tried to implement a basic webpack setup for the assets in my Django project and replaced django-compressor.

In the main script I simply tested to initialize flowbite when an htmx request loads.

// Initialize Flowbite
import { initFlowbite } from 'flowbite';

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

This works, but is extremely slow and buggy when I scroll the page. (Not if I comment out the initFlowbite).
Also, this initialization creates multiple modal-backdrops at the end of the body tag. This results in an ugly and unperformant UI.

Any recommendations or solutions?

@zoltanszogyenyi zoltanszogyenyi self-assigned this Jun 3, 2023
@zoltanszogyenyi
Copy link
Member

Hey everyone,

With the new release of v1.6.6 you should now be able to access all init functions including initFlowbite via the window object - I believe a part of the import problems should be addressed.

Regarding more advanced ways of initialising the event listeners we'll have to make a more comprehensive update that uses advanced verifications so we only init the newly added items to the DOM.

Cheers,
Zoltan

@msm1227
Copy link

msm1227 commented Sep 18, 2023

I am having a similar issue and it may just boil down to me not knowing how to implement it.

I have a modal (with an id of "pro") that I would like to pop up after a certain amount of time and won't have a button on the page for it. How would I go about doing this?

Thanks!

@zoltanszogyenyi
Copy link
Member

Hey everyone!

Flowbite v2.0 fixes this issue by bringing a brand new Instances Manager.

Please read more about it here:

https://flowbite.com/docs/getting-started/javascript/
https://github.com/themesberg/flowbite/releases/tag/v2.0.0

Cheers,
Zoltan

@Ifedi
Copy link

Ifedi commented Mar 4, 2024

I'm struggling frustratedly to see how this issue is "completed". It's all well to say you have solved the issue with "Instances Manager".
Please, how difficult is it to present a simple example of how to initialize the interactivity of Modal, Dropdown, Drawer, etc whenever a new element bearing the flowbite data attributes is DYNAMICALLY ADDED to the page in vanilla JS?

I'm really confused since I'd assume that this is a very basic scenario that ought to be covered in a framework like this. Any suggestion for me to implement the details myself defeats the whole purpose of using a framework such as this in the first place!

@georgekronberg
Copy link

Same question, how do I use Instances Manager to make fix the problem with subsequence calls to initFlowbite creating additional bindings for existing already bound components?

@zachbellay
Copy link

Looks like @samld was kind enough to make a PR for changes to support this!

Would suggest showing your support to get it merged: #824

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

No branches or pull requests

10 participants