- Custom confirm dialogs via
@rolemodel/turbo-confirm
integration - Modal and panel styling ..via
@rolemodel/optics
integration - Modal and panel layouts w/ link helpers (or you could just, e.g.
link_to ... data: {turbo_frame: 'modal'}
) - frame-missing handler (required for turbo-rails v1.4.0 and above)
- a very simple stimulus controller
toggle
to help with modal/panel animations.
- This generator does not currently attempt to remove the old RoleModel Modal/Confirm/Panel or MakeFormsRemote javascript files or initialization code. However, that code needs to be removed for the new process to work correctly.
- Remove Rails-UJS from your project. Most likely that means running
yarn remove @rails/ujs
and then deleting theimport
andstart()
statements from application.js. - Ensure your application layout now includes the empty
turbo_frame_tag
s formodal
&panel
as well as the new confirm partial. The generator should have done this but it may have failed if your layout is much different than expected.
= button_to "Test Confirm", model, method: :delete, data: { \
turbo_confirm: "For real?!?",
confirm_details: "You're about to delete #{model.name}, forever. 😱",
confirm_button: "YOLO!",
}
data attributes other than turbo-confirm
are optional. See turbo-confirm for more details.
Modal: (the following 2 examples are equivalent)
= link_to 'Modal Test', some_modal_layout_action_path, data: { turbo_frame: 'modal' }
= modal_link_to 'Modal Test', some_modal_layout_action_path
Panel: (the following 2 examples are equivalent)
= link_to 'Panel Test', some_panel_layout_action_path, data: { turbo_frame: 'panel' }
= panel_link_to 'Panel Test', some_panel_layout_action_path
You'll then need to pass the layout
kwarg when calling render
with either modal
or panel
, depending on which frame is being targeted. (We recommend against the layout
controller class method, because it causes layout fallback issues when the controller is subclassed.)
e.g.
class SomethingsController < ApplicationController
def new
render layout: 'modal'
end
end
There are a couple of important rules when it comes to TurboFrames & forms.
- In the case of errors, your controller action must respond with
status: :unprocessable_entity
HTTP status code 422 in order to re-render your form w/ errors. This is both a Turbo requirement, as well as the mechanism which prevents the modal or panel from re-animating in. - In the case of success, your controller action must redirect. This is a Turbo requirement in Rails 7+
e.g.
class SomethingsController < ApplicationController
def new
@something = authorize Something.new
render layout: 'modal'
end
def create
@something = authorize Something.new(some_params)
if @something.save
redirect_to @something, notice: 'Something created successfully'
else
render :new, status: :unprocessable_entity, layout: 'modal'
end
end
end
The included modal layout includes slots for title content & submit buttons, in addition to the main content yield
. You may, of course remove these sections if they don't match your use-case. Otherwise, the following is an example edit template meant to be rendered in the modal layout.
= content_for :modal_title do
h2 Edit the thing
= content_for :modal_actions do
= button_tag 'Save', class: 'btn btn--primary', form: dom_id(@thing, :edit)
= simple_form_for @thing do |f|
= f.input :name
= f.input :description
note: the submit button in the new.html.slim
version of this template would be form: dom_id(@thing)
or simply form: 'new_thing'
.
Alternatively, it's still possible to nest the content_for
block within the form builder if you need to leverege button text generation, for example. Though you must still set the form
attribute explicitly, because the button (or input[type='submit']
in this case) will ultimately be rendered outside of the <form></form>
tags. e.g.
= simple_form_for @thing do |f|
= f.input :name
= f.input :description
= content_for :modal_actions do
= f.submit form: f.id
For further explanation of form Id generation, see the Record Identifier and polymorphic Routes docs, or simply inspect the form element in your browser.