Skip to content

Instantly share code, notes, and snippets.

@codeprimate
Created June 11, 2009 20:29
Show Gist options
  • Save codeprimate/128218 to your computer and use it in GitHub Desktop.
Save codeprimate/128218 to your computer and use it in GitHub Desktop.
<div class="form">
<div class="spacer"><!-- --></div>
<div class="yui-g productdetailpaddingh">
Create your Profile
| Step <%= step_number %> of <%= total_steps %>
</div>
<p>
<% unless step_number <= 1%>
<%= link_to("Back", {:controller => :profile_wizard, :action => :previous_step}) %>
<%= link_to("Reset", {:controller => :profile_wizard, :action => :reset}, :confirm => "Are you sure you want to restart the profile wizard?") %>
<% end %>
<%= link_to("Next", {:controller => :profile_wizard, :action => :next_step}) if step_completed %>
</p>
<h1>Company Profile</h1>
<% form_for(@company, :url => wizard_path, :html => {:method => :put, :multipart => true}) do |company_form| %>
<%= error_messages_for :company %>
<%= render :partial => "company/form", :locals => {:company_form => company_form} %>
<%= company_form.submit "Save" %>
<% end %>
</div>
#Example Class
class ProfileWizardController < WizardController
define_steps :profile, :review_profile, :company, :review_company
set_default_error "There was a problem processing the last step!"
before_filter :login_required
skip_before_filter :store_location
def company
user_company
end
def process_company
user_company.attributes = params[:company]
if user_company.save
current_user.company_id = user_company
current_user.save
return true
else
return false
end
end
def review_company
no_processing
user_company
end
def profile
user_profile
end
def process_profile
user_profile.attributes = params[:profile]
if user_profile.save
current_user.reload
return true
else
return false
end
end
def review_profile
no_processing
user_profile
end
private
def user_company
@object = @company ||= current_user.company || current_user.build_company
end
def user_profile
@object = @profile ||= current_user.profile || current_user.build_profile
end
end
class WizardController < ApplicationController
before_filter :restrict_access, :init_wizard_session
### CLASS METHODS
class << self
@wizard_steps = []
@finish_path = '/'
@wizard_default_error = 'There was a problem processing the last step.'
attr_accessor :wizard_steps, :finish_path, :wizard_default_error
def define_steps(*args)
self.wizard_steps = args
end
def set_finish_path(p)
self.finish_path = p
end
def set_default_error(e)
self.wizard_default_error = e
end
end
### PUBLIC ACTIONS
def index
if finished
handle_finished_wizard
else
handle_unfinished_wizard
end
end
def next_step
if step_completed
incr_step
else
flash[:error] ||= self.class.wizard_default_error
end
redirect_to :action => :index
end
def previous_step
decr_step
redirect_to :action => :index
end
def reset
reset_wizard
redirect_to :action => :index
end
private
### PRIVATE CONTROLLER METHODS
def handle_finished_wizard
redirect_to finish_path
reset_wizard
end
def handle_unfinished_wizard
if request.get?
handle_get_action
else
handle_post_action
end
end
def handle_get_action
execute_method
render_step_view
end
def handle_post_action
if (self.wizard_step_completion = execute_process_method)
next_step
else
flash[:error] ||= self.class.wizard_default_error
render_step_view
end
end
def restrict_access
['index', 'next_step', 'previous_step', 'reset'].include?(params[:action])
end
def execute_method(m=current_wizard_step_method)
return send(m)
end
def execute_process_method
return execute_method("process_#{current_wizard_step_method}".to_sym)
end
def render_step_view
render :action => current_wizard_step_method
end
helper_method :step_number
def step_number
current_wizard_step
end
helper_method :total_steps
def total_steps
self.class.wizard_steps.size
end
helper_method :next_step_path
def next_step_path
url_for(:controller => self.controller_name, :action => :next_step)
end
helper_method :previous_step_path
def previous_step_path
url_for(:controller => self.controller_name, :action => :previous_step)
end
helper_method :step_completed
def step_completed
session[:wizard][self.class.to_s][:completed][current_wizard_step] == true
end
helper_method :wizard_path
def wizard_path
url_for(:controller => self.controller_name)
end
#### SESSION MANAGEMENT
def current_wizard_step
@wizard_step ||= session[:wizard][self.class.to_s][:step].to_i
end
def set_current_wizard_step(step)
session[:wizard][self.class.to_s][:step] = step
@wizard_step = step
end
def incr_step
set_current_wizard_step(current_wizard_step + 1)
end
def decr_step
set_current_wizard_step([1, (current_wizard_step - 1)].max)
end
def current_wizard_step_method
self.class.wizard_steps[(current_wizard_step - 1)]
end
def finished
self.class.wizard_steps.size < current_wizard_step
end
def finish_path=(p)
unless p.blank?
session[:return_to] = p
end
finish_path
end
def finish_path
session[:return_to]
end
def no_processing
self.wizard_step_completion = true
end
def set_as_not_completed
self.wizard_step_completion = false
end
def wizard_step_completion=(completed)
session[:wizard][self.class.to_s][:completed][current_wizard_step] = completed
end
def reset_wizard
session[:wizard][self.class.to_s] = nil
init_wizard_session
end
def init_wizard_session
session[:wizard] ||= {}
session[:wizard][self.class.to_s] ||= {}
session[:wizard][self.class.to_s][:step] ||= 1
session[:wizard][self.class.to_s][:completed] ||= {}
session[:return_to] ||= self.class.finish_path
@wizard_step = session[:wizard][self.class.to_s][:step].to_i
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment