Hat Trick
Multi-step "wizard" forms in Rails using jQuery. Keeps your controller CRUD methods clean with a wizard DSL.
Install
gem install hat-trick
Rails 3.1+
(older versions not supported)
Put this in your Gemfile:
gem 'hat-trick'
Setup
In your controller:
wizard do
step :first_step
step :second_step
step :third_step
end
Make sure your controller's CRUD methods know how to return JSON responses containing the model instance you're building in the wizard.
In your view:
<%= wizard_form_for @model do |f| %>
<fieldset id="first_step">...</fieldset>
<fieldset id="second_step">...</fieldset>
<fieldset id="third_step">...</fieldset>
<% end %>
The id's of the fieldsets in your form should match the step names you define in your controller.
Each fieldset will be displayed as a step with Next and Back buttons.
Controlling the wizard flow
Sometimes you need to specify different paths through a wizard based on certain conditions. The way you do that with hat-trick is in the wizard DSL in the controller. Here are some examples:
Jumping to a step based on logged in status:
wizard do
step :first_step do
# after defines a callback to run after the current step is completed by the user
after do
# code in this block will be exec'd in the context of your controller
if current_user?
next_step :third_step
end
end
end
step :second_step # wizard will go here after :first_step if user is not signed in
step :third_step # wizard will go here after :first_step if user is signed in
Skipping a step under certain conditions:
wizard do
step :first_step
step :second_step do
# before defines a callback to run before the user sees this step
before do
# code in this block will be exec'd in the context of your controller
skip_this_step unless model.foo.present?
end
end
end
Using the model instance in before and after callbacks:
wizard do
step :first_step do
before do |model_instance|
if model_instance.attr.present?
next_step :third_step
end
end
end
end
Customizing the button labels:
wizard do
button_label :next, "Onward!"
button_label :back, "Engines reverse full"
end
Adding a custom button to a step:
wizard do
step :first_step do
button_to :next, name: "model[button_name]", label: "Foobar"
end
end