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

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

Closed
akyoscommunication opened this issue Jun 17, 2022 · 8 comments · Fixed by #728
Closed

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

akyoscommunication opened this issue Jun 17, 2022 · 8 comments · Fixed by #728

Comments

@akyoscommunication
Copy link

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
Copy link
Member

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
Copy link
Author

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

@akyoscommunication
Copy link
Author

Miss click, sorry, that's not closed

@weaverryan
Copy link
Member

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
Copy link
Author

akyoscommunication commented Jun 22, 2022

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

@janklan
Copy link
Contributor

janklan commented Aug 8, 2022

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
Copy link
Author

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.

weaverryan added a commit that referenced this issue Aug 14, 2022
…o play nicely (weaverryan)

This PR was merged into the 2.x branch.

Discussion
----------

[LiveComponent][Autocomplete] Adding support for libraries to play nicely

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no (but yes to BC break)
| Tickets       | Fixes #407 and helps with #354
| License       | MIT

See the commit for more information - this was a VERY pesky bug.

Cheers!

Commits
-------

c4791fc [LiveComponent][Autocomplete] Adding support for libraries to play nicely together
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

Successfully merging a pull request may close this issue.

3 participants