Turbo frames conditional rendering
See original GitHub issueI want to stick a form in a modal, using a link that will request the new
action to render the form HTML which then gets injected into the modal and opened.
This is a pretty common pattern that I’ve implemented many times before with Rails UJS.
I am now trying to do the same thing with Turbo.
<%# index.html.erb %>
<%= link_to 'New Post', new_post_path, data: { 'turbo-frame': 'modal-body' } %>
<div class="modal" data-controller="modal">
<%= turbo_frame_tag "modal-body", 'data-action': 'turbo:frame-render->modal#show' %>
</div>
<%# new.html.erb %>
<h1>New Post</h1>
<%= turbo_frame_tag "modal-body" do %>
<%= form_with(model: @post) do |form| %>
<div class="field">
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
<% end %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
So I have a pre-rendered empty modal with turbo_frame_tag
in the modal body. When I click the link, the controller renders the new
template which has the form wrapped in a matching turbo_frame_tag
. The form gets injected into the modal and I have a stimulus controller which opens the modal on turbo:frame-render
.
This works pretty well, but there seems to be a pretty big limitation - The form HTML has to be identical for both the modal, and for when I visit the new URL directly. For example, if I need a close button when in a modal, but a cancel link when visiting the page directly, this doesn’t seem possible to handle server-side.
With Rails UJS, My new
controller action could respond to format.js
for the modal and format.html
when visiting directly, making it possible to render different HTML. As new
action is a GET, this rules out format.turbo_stream
which is for non-GET requests only.
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
I suggested this as a default in the turbo-rails gem
see: https://github.com/hotwired/turbo-rails/issues/229
Thanks @tleish, variants work brilliants actually. It works without the boilerplate
format.html do |variant|
in the controller too, as long as the variant is set in the before action it renders the variant template if it exists.Is there any harm to putting
turbo_frame_request_variant
inApplicationController
before all request?