ux
ux copied to clipboard
[LiveComponent] Using other UX components in Live form
Hi,
I'm testing Live Components to make multiple steps forms with live validation. That's working fine! The tricky part is to use some js libs like datepicker, select-2, etc.. but with Stimulus controllers that works fine too. The missing thing is that other ux component doesn't work at all together. What could we do to make autocomplete, dropzone or even turbo work inside Live components ?
Hey @akyoscommunication!
This is something I've thought about, but haven't played with yet. In theory, they should work fine, because Stimulus "always works". However, in practice, it's possible that the re-rendering of live components will basically reset/reinitialize certain fields that have another component attached to it (e.g. autocomplete).
What bad behavior have you seen with mixing components inside of Live components? I would expect some to work fine - like Turbo - but others might need some help (e.g. autocomplete). One option is to use data-live-ignore
on some of these elements - https://symfony.com/bundles/ux-live-component/current/index.html#skipping-updating-certain-elements - but that should really be a "last resort": we should make the components "play nicely" inside of live components as much as possible with no extra work.
Cheers!
Hey,
Yes Stimulus controllers still works, but on each blur of a field or on each live action, Live component re-renders: some ux components like dropzone are resetted but still works (value is lost but we can continue put files in it), some others like autocomplete doesn't work anymore (JS code doesn't re-init automatically). We also tried Turbo to add some sub-component (push a "notification" component in a list) but we have some checksum problems..
Exemple with autocomplete (no css) : https://watch.screencastify.com/v/bwvcZrVCsRSMUjYiXwoR
Maybe the dropzone problem will disappear when issue #289 will be merge. For autocomplete (and incoming Datepicker, Map, etc..), some idea:
- In Stimulus controller, detect on connect if the element is in a Livecomponent
- If so, store needed values (file input, select value, ...) in a variable and add a listener / a mutation observer on element.
- When mutation is triggered, destroy instance if still running, re-build it, and re-set the value
I made something like this with Datepicker and CKEDitor: https://watch.screencastify.com/v/731WxuOxx2DJdamkeAei , but there's still some bugs when component rerenders, it disappears before re-init js.
Thanks
Miss click, sorry, that's not closed
Thanks for all the extra info!
We also tried Turbo to add some sub-component (push a "notification" component in a list) but we have some checksum problems
Can you explain this further? Are you using a <turbo-frame>
or Turbo streams to push a notification component into a list? This, at first, sounds legit: if things are working properly, you should never get a checksum issue.
Hello !
In my case, i'm using mercure to push my new notification. I queuing that with this function :
$this->hub->publish(new Update( 'notifications', $this->renderView('stream/notifications.stream.html.twig', ['notification' => $notification]) ));
In my template, i have this :
<turbo-stream action="update" target="Notifications"> <template> {{ component('notification-popup', {member: notification.member}) }} </template> </turbo-stream>
So, i update this part of code:
<div id="Notifications" {{ turbo_stream_listen('notifications') }}>{{ component('notification-popup', {member: app.user}) }}</div>
In this case, I update the whole popup to have the filters up to date. I also tried to append only one notification in my ul but it still doesn't work...
What I'm trying to do is make it so that when we click on the notification, it puts it in "view" and we are redirected with this :
#[LiveAction] public function seen(#[LiveArg] int $id) { $notification = $this->em->getRepository(Notification::class)->find($id); $notification->setIsSeen(true); $this->em->flush(); if ($notification->getRedirectTo()) { return $this->redirect($notification->getRedirectTo()); } }
I think the problem is due to the fact that I append my component which does not have the right "data-live-csrf-value". I make a video to illustrate the process.
Thanks
https://drive.google.com/file/d/11ojIPv7OK_Ure1Z_gDdd3kuiX21Vl59b/view?usp=sharing
Yes Stimulus controllers still works, but on each blur of a field or on each live action, Live component re-renders: some ux components like dropzone are resetted but still works (value is lost but we can continue put files in it), some others like autocomplete doesn't work anymore (JS code doesn't re-init automatically).
Just FYI, the Autocompleter had a bug preventing it form working in live component. That's about to be fixed.. Maybe other components have similar issues?
It's also possible to listen for live:* events and act on them - or example, re-creating an instance of third party component that otherwise relies on domready or load events etc. Your mileage will vary, but that's why this is an experimental feature. All feedback is important.
Yeah we did custom datepicker field listening live events to reload third party library on each re-render. Also created custom file upload functionnality with dropzone.js in a subcomponent with data-live-ignore that update an hidden field in parent component and upload file in a temp directory using AJAX (same idea as #395).
Ux Components are already awesome, I think the best one are LiveComponent for formModifiers, collections and awesome UX without Js. Just missing 3 things: Autocomplete for large entityTypes, Dropzone for file uploads, and Turbo for real time events (re-render live components on external change without polling). Those 3 components already exists, but none is playing well inside LiveComponents.