Description
I'm not a front-end dev primarily, so I might be wrong, but I'll try my best to be right.
Rails framework has Turbo, which is a way to transition between urls by replacing page body with javascript (ajax), instead of reloading normally. I tried to make it work with Tabler, and got pretty close.
I can add Tabler library as a normal <script src="…">, but the problem is, this script wants to be fully reloaded in order to populate event listeners. Turbo will not reload this script on page transitions. So if a page transition happened, event listeners are lost, and tabler will never re-bind them.
If you're stubborn like me, and you want Tabler to work with Turbo, you can use a turbo hook called "turbo:load", which fires on both initial page load, and turbo transition. In that hook I wrote an ugly hack that removes and adds back the <script> tag each time, so that tabler gets reloaded.
This actually worked, all Tabler features started working with Turbo, yay! But now, bootstrap javascript behavior stopped working. Why? I'm not even requiring bootstrap myself, it's vendored in Tabler.
Well, it seems that Bootstrap adds all event listeners to the document object every time it's loaded, and since Turbo won't replace the document object, event listeners just keep getting added indefinitely. On each page transition I get another set of duplicate event listeners. This is bad in itself, but it really messes with the "toggle" functionality, because now when I, say, expand a navbar, it works, but when I try to collapse it, it collapses and expands again, making it seem like collapse doesn't work, because it seems multiple events toggle it back and forth. (I observed it step-by-step in a debug session.)
Can we make a small change to fix everything?
Describe the solution you'd like
I really hope this is a small change and it does what I think it does. Instead of having all the event-binding code loose in tabler.js, wrap it into a function. And to keep everything working the same way for everyone, just call this function immediately after. That's it.
Like:
function tablerInit {
// everything that tabler.js does
}
tablerInit();
No behavior changed, but now I can call this function in a turbo hook to repopulate the listeners after page transitions. So now I can remove the ugly hack that re-inserts the <script>, and no longer worry about bootstrap loading repeatedly.
Describe alternatives you've considered
I've explored trying to clear the event listeners myself, but that quickly gets even uglier. I considered completely disabling turbo, but that feels incredibly unsatisfying when the solution seems so close (if I understood it correctly).
Another alternative solution might be for tabler to also attach all events to document, like bootstrap does. (But I don't know enough js to understand the implications of this.) 🤷🏻♂️
Would appreciate any feedback. Maybe this function already exists, and I didn't find it?