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

turbo_refreshes_with morph-reset, replace-preserve #536

Open
yshmarov opened this issue Dec 7, 2023 · 7 comments
Open

turbo_refreshes_with morph-reset, replace-preserve #536

yshmarov opened this issue Dec 7, 2023 · 7 comments

Comments

@yshmarov
Copy link

yshmarov commented Dec 7, 2023

Hi! I currently see 2 turbo_refreshes_with options:

# default
turbo_refreshes_with method: :replace, scroll: :reset
# enable morphing
turbo_refreshes_with method: :morph, scroll: :preserve

Are there any scenarios where replace-preserve, morph-reset` would be preferable? If not, why is this possible?

turbo_refreshes_with method: :replace, scroll: :preserve
turbo_refreshes_with method: :morph, scroll: :reset
@ArturT
Copy link

ArturT commented Dec 12, 2023

I noticed that when you do not provide :method (which means using method: replace) to turbo_refreshes_with then Stimulus controller runs connect() function correctly when page changes.

But if you use method: :morph then Stimulus connect() function sometimes does not start and this can cause problems with rendering your Stimulus controller. For example if you have a table with 100 rows. You added new data to the table (1st row added, last row removed). In such case the 1st row will be updated by morphing and Stimulus controller won't start connect() function. You need to detect change in your Stimulus controller for example using callbacks for value changed.

@jon-sully
Copy link

This is more a question of what the Turbo library itself supports functionally (turbo-rails just adds nice bindings for us), but for the question at hand, I don't know that:

turbo_refreshes_with method: :replace, scroll: :preserve

Is actually useful or intended to be used, really. By using "replace" you're indicating that there's a navigation to a new 'content page' which typically means scroll should reset so the user can begin seeing/grokking the content anew. So pairing it with scroll: :preserve feels odd. That use case might be out there, but I imagine it rare.

On the other hand, and the very reason I believe the Turbo team opted to split the :scroll option from the :method option in the first place, is that:

turbo_refreshes_with method: :morph, scroll: :reset

Has legitimate use-cases. I can't tell you exactly what they are, but I recall someone on the HEY Calendar team mentioning that the Calendar workflow has a couple of places where morphing was appropriate (so some kind of page refresh / update to an existing content page; not a navigation to a new content page) but even in staying on the same content page, resetting the scroll felt appropriate / necessary too.

Maybe think of a long form with lots of markup content and when you submit that form you get back a "Thanks!" followed by lots of follow-up instructions / markup. There might be a case there where you want to morph because you're still looking at the same canonical content page, but perhaps reset the scroll to help the user start reading the instructions fresh.

@ArturT
Copy link

ArturT commented Dec 24, 2023

I have a use case where the following is needed:

turbo_refreshes_with method: :replace, scroll: :preserve

I use the chartkick gem to render charts with js. The chart is refreshed only if I use the replace method. In case of morphing then chart is not rendered on the refresh.

@jon-sully
Copy link

I imagine that kind of scenario is more of an implementation detail / issue with how the morphing works (noted in hotwired/turbo#1083) rather than a functional desire for replace+preserve. E.g., if morphing did preserve your charts, you'd probably use morphing then?

@ArturT
Copy link

ArturT commented Dec 24, 2023

You are correct.

@yshmarov
Copy link
Author

yshmarov commented Dec 24, 2023

But if you use method: :morph then Stimulus connect() function sometimes does not start and this can cause problems with rendering your Stimulus controller.

Indeed, I've been having the same issue with stimulus controllers not reconnecting (for example a dropdown not staying open after morph.

Combining these methods in various ways helped me:

  • data-turbo-permanent
  • reconnect a stimulus controller after morph data-action="turbo:morph@window->dropdown#connect"
  • handle (reset) form submission data-action="turbo:submit-end->dropdown#close turbo:submit-end->form-reset#connect"

@jon-sully
Copy link

jon-sully commented Dec 24, 2023

FYI hotwired/turbo#1097 aims to help with some of these ^. I imagine it'll be merged soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants