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

Phoenix Liveview: Flowbite elements that require js do not work in content pushed to the client after initial page load #869

Open
DennisNissen opened this issue Apr 29, 2024 · 0 comments

Comments

@DennisNissen
Copy link

Describe the bug
Flowbite elements that require javascript do not work or stop working when added to the dom with a liveview update. This is especially uncomfortable when using async data fetching and using flowbite components (f.e. Accordions) or when you update dom elements with server pushes.

Expected behavior
Flowbite elements do always work, even when added to the dom with a liveview update.

Desktop (please complete the following information):

  • OS: MacOS
  • Browser: Edge
  • Version 124.0.2478.51

Additional context

Example:

<.async_result :let={time_entries} assign={@time_entries}>
  <:loading>
    <div class="flex items-center mt-5">
      <span class="loading loading-spinner loading-lg"></span>&nbsp; Loading time entries and combining them with gitlab issues
    </div>
  </:loading>
  <:failed :let={_failure}>Error loading time entries or gitlab issues</:failed>
  
 <div data-accordion="collapse" id="example-accordion">
   <button data-accordion-target={"#detail-#{issue}"}>Click me</button>
   <div class="hidden" id={"detail-#{issue}"}>
     important informations
   </div>
 </div>
</.async_result> 

The example-accordion's content is pushed to the client after the async data loading has finished and flowbite elements in the result will not work.

Liveview's dom hook has the ability to apply javascript to the dom elements that are pushed to the client with

let liveSocket = new LiveSocket("/live", Socket, {
  params: {_csrf_token: csrfToken},
  dom: {
    onBeforeElUpdated(from, to) {
     //copy attributes from "from" to "to" or apply function on "to"  
    }
  }
})

But the init.... (f.e. initAccordions) functions are using document.querySelectorAll() and thus are unable to be scoped to the incoming DOM nodes.

A workaround for now is to apply a custom hook to the parent node

const Hooks = {}
Hooks.Flowbite = {
  mounted(){
    initFlowbite();
  }
  updated(){
    this.mounted()
  }
}

let liveSocket = new LiveSocket("/live", Socket, {
    params: {_csrf_token: csrfToken}, hooks: Hooks
})

and in the template file

...
<div phx-hook="Flowbite">
 <div data-accordion="collapse" id="example-accordion">
   <button data-accordion-target={"#detail-#{issue}"}>Click me</button>
   <div class="hidden" id={"detail-#{issue}"}>
     important informations
   </div>
 </div>
</div>
...

This works, but triggers a lot of init functions for each update. It would be great to be able to apply the init functions to the dom elements that are updated.

@DennisNissen DennisNissen changed the title Phoenix Liveview: Flowbite elements that require js do not work on content pushed to the client after initial page load Phoenix Liveview: Flowbite elements that require js do not work in content pushed to the client after initial page load Apr 30, 2024
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