symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
820 stars 297 forks source link

[LiveComponent] Using other UX components in Live form #354

Closed akyoscommunication closed 1 year ago

akyoscommunication commented 2 years ago

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 ?

weaverryan commented 2 years ago

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!

akyoscommunication commented 2 years ago

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:

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

akyoscommunication commented 2 years ago

Miss click, sorry, that's not closed

weaverryan commented 2 years ago

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.

akyoscommunication commented 2 years ago

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 : `

`

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

akyoscommunication commented 2 years ago

https://drive.google.com/file/d/11ojIPv7OK_Ure1Z_gDdd3kuiX21Vl59b/view?usp=sharing

janklan commented 2 years ago

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.

akyoscommunication commented 2 years ago

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.