hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.71k stars 427 forks source link

Add option to opt out of Turbo for forms by default and require manual opt in #244

Closed ayushn21 closed 4 months ago

ayushn21 commented 3 years ago

Anecdotally, one of the biggest deterrents for people upgrading from Turbolinks to Turbo has been the way forms are handled. For Rails users heavily invested in UJS, it's a mammoth task to rework all the forms to work with Turbo.

I've worked around this in the past in Rails by monkey patching form_with to disable Turbo with data-turbo=false; but I think it'd be a great idea to allow a global setting within Turbo to navigate only on forms that have opted in with data-turbo=true.

I'm thinking it could be set at initialization time like: Turbo.start({ forms_opt_out_by_default: true })

I'm happy to spend some time working on this if this is something maintainers would like to support so just opening this issue to get people's thoughts!

seanpdoyle commented 3 years ago

@ayushn21 have you tried setting <html data-turbo="false"> or <body data-turbo="false">, and then incrementally opting into Turbo on an individual <a> and <form> basis?

If it's <form> elements that are the issue, It might be more straightforward to disable all elements, and then opt back in <a> elements:

addEventListener("turbo:load", () => {
  for (const link of document.querySelectorAll("a")) {
    link.setAttribute("data-turbo", "true")
  }
})
leastbad commented 3 years ago

Hey @seanpdoyle that is a good solution in the short term. Thanks!

Bigger picture, it seems like if the UJS remote form behaviour was managed via the config.action_view.form_with_generates_remote_forms in your environment, there should also be an equivalent config.action_view.form_with_generates_turbo_forms or similar.

Am I totally out to lunch or does this make some sense?

seanpdoyle commented 3 years ago

config.action_view.form_with_generates_turbo_forms

I think that's totally reasonable. At the moment, Action View is completely unaware of Turbo, and I'm not aware of any Rails mechanism to set default options for helper methods.

At a high level, what would you like to see happen when config.action_view.form_with_generates_turbo_forms is true?

leastbad commented 3 years ago

Not coincidentally, we were doing a fair bit of digging on this last night in the StimulusReflex Discord.

Ultimately, the token form_with_generates_remote_forms shows up in just six files, most specifically in form_helper.rb.

The way I would approach this is that right now, it's almost as if there's already an invisible form_with_generates_turbo_forms setting that defaults to true. 😉

If this value was set to false, we'd add a data-turbo="false" attribute to the form helper.

ayushn21 commented 3 years ago

Thanks @seanpdoyle. That's a great stopgap solution on the JS side of things.

I do agree with @leastbad that it'd be great to have a cleaner way to prevent Turbo from navigating on forms by default though. The chat we were having in the StimulusReflex Discord was also centered on what level should this setting be configured (i.e. within Turbo or through a server side helper like config.action_view.form_with_generates_turbo_forms)

If you believe the right way to go about this would be to handle the exclusion of forms on the server rather than within Turbo, I reckon it makes sense to close this issue and we can take the discussion to rails/rails.

Thanks for your input!

brunoprietog commented 4 months ago

Addressed in #419