lib/hat_trick/dsl.rb in hat-trick-0.1.2 vs lib/hat_trick/dsl.rb in hat-trick-0.1.3
- old
+ new
@@ -4,143 +4,237 @@
module HatTrick
module DSL
extend ActiveSupport::Concern
- attr_accessor :ht_wizard, :configure_callback, :_ht_config
+ attr_accessor :hat_trick_wizard
- delegate :model, :previously_visited_step, :to => :ht_wizard
+ delegate :model, :previously_visited_step, :to => :hat_trick_wizard
- included do
- alias_method_chain :initialize, :hat_trick
- end
-
- def initialize_with_hat_trick(*args)
- @_ht_config = HatTrick::Config.new(self.class.wizard_def)
- if configure_callback.is_a?(Proc)
- ht_wizard.controller.instance_exec(@_ht_config, &configure_callback)
- end
- initialize_without_hat_trick(*args)
- end
-
def next_step(name=nil)
if name.nil?
# getter
- ht_wizard.next_step
+ hat_trick_wizard.next_step
else
# setter
- step = ht_wizard.find_step(name)
+ step = hat_trick_wizard.find_step(name)
# explicitly set steps should not be skipped
step.skipped = false
- ht_wizard.current_step.next_step = step
+ hat_trick_wizard.current_step.next_step = step
end
end
+ def previously_visited_step_name
+ if previously_visited_step.nil?
+ ''
+ else
+ previously_visited_step.name
+ end
+ end
+
def skip_this_step
- ht_wizard.skip_step(ht_wizard.current_step)
+ hat_trick_wizard.skip_step(hat_trick_wizard.current_step)
end
+ def button_to(step_name, options={})
+ button = self.class.send(:create_button_to, step_name, options)
+ hat_trick_wizard.current_step.add_button button
+ end
+
+ def remaining_step_count
+ hat_trick_wizard.steps_after_current
+ end
+
+ def adjust_remaining_step_count_by(diff)
+ hat_trick_wizard.steps_remaining += diff
+ end
+
+ def change_remaining_step_count_to(count)
+ hat_trick_wizard.steps_remaining = count
+ end
+
+ def total_step_count
+ hat_trick_wizard.total_step_count
+ end
+
+ def reset_step_count
+ hat_trick_wizard.override_step_count = nil
+ end
+
+ def redirect_to_step(step_name)
+ hat_trick_wizard.redirect_to_step step_name
+ end
+
+ def redirect_to_external_url(url)
+ hat_trick_wizard.external_redirect_url = url
+ end
+
module ClassMethods
attr_reader :wizard_def
def wizard(&block)
if block_given?
include HatTrick::DSL::ControllerInstanceMethods
include HatTrick::ControllerHooks
- @wizard_def = HatTrick::WizardDefinition.new
+ ::ActiveRecord::Base.send(:include, HatTrick::ModelMethods)
+ config = HatTrick::Config.new
+ @wizard_def = HatTrick::WizardDefinition.new(config)
+
yield
else
raise ArgumentError, "wizard called without a block"
end
end
def configure(&block)
raise "Must pass a block to configure" unless block_given?
- @config_callback = block
+ self.configure_callback = block
end
+ def button_label(type, label)
+ wizard_def.config.send("#{type}_button_label=", label)
+ end
+
+ def button_label_i18n_key(type, i18n_key)
+ wizard_def.config.send("#{type}_button_label_i18n_key=", i18n_key)
+ end
+
def step(name, args={}, &block)
raise "step must be called from within a wizard block" unless wizard_def
wizard_def.add_step(name, args)
instance_eval &block if block_given?
end
- def repeat_step(name)
- raise "repeat_step must be called from within a wizard block" unless wizard_def
- repeated_step = wizard_def.find_step(name)
- raise ArgumentError, "Couldn't find step named #{name}" unless repeated_step
- new_step = repeated_step.dup
- # use the repeated step's fieldset id
- new_step.fieldset = repeated_step.fieldset
- # but use the current step's name
- new_step.name = wizard_def.last_step.name
- # replace the step we're in the middle of defining w/ new_step
- wizard_def.replace_step(wizard_def.last_step, new_step)
- end
-
def skip_this_step
# skip_this_step in wizard definition (class) context means the step
# can be explicitly jumped to, but won't be visited in the normal flow
raise "skip_this_step must be called from within a wizard block" unless wizard_def
wizard_def.last_step.skipped = true
end
- def button_to(name, options=nil)
+ def last_step
+ raise "skip_this_step must be called from within a wizard block" unless wizard_def
+ wizard_def.last_step.last = true
+ end
+
+ def button_to(step_name, options={})
raise "button_to must be called from within a wizard block" unless wizard_def
- label = options[:label] if options
- label ||= name.to_s.humanize
+ wizard_def.last_step.add_button create_button_to(step_name, options)
+ end
- id = options[:id] if options
-
+ def hide_button(button_type)
+ raise "before must be called from within a wizard block" unless wizard_def
step = wizard_def.last_step
- button = { :label => label }
- button[:id] = id unless id.nil?
- step.buttons = step.buttons.merge(name => button)
+ step.delete_button button_type
end
- def before(&block)
+ def before(scope=:current_step, &block)
raise "before must be called from within a wizard block" unless wizard_def
- wizard_def.last_step.before_callback = block
+ if scope == :each
+ wizard_def.before_callback_for_all_steps = block
+ else
+ wizard_def.last_step.before_callback = block
+ end
end
- def after(&block)
+ def after(scope=:current_step, &block)
raise "after must be called from within a wizard block" unless wizard_def
- wizard_def.last_step.after_callback = block
+ if scope == :each
+ wizard_def.after_callback_for_all_steps = block
+ else
+ wizard_def.last_step.after_callback = block
+ end
end
def include_data(key, &block)
raise "include_data must be called from within a wizard block" unless wizard_def
wizard_def.last_step.include_data = { key.to_sym => block }
end
def set_contents(&block)
raise "set_contents must be called from within a wizard block" unless wizard_def
- current_step_name = wizard_def.last_step.to_sym
- include_data "hat_trick_step_contents" do |wiz, model|
- { current_step_name => instance_exec(wiz, model, &block) }
+ wizard_def.last_step.step_contents_callback = block
+ end
+
+ private
+
+ def configure_callback
+ @configure_callback
+ end
+
+ def configure_callback=(block)
+ @configure_callback = block
+ end
+
+ def create_button_to(to_step_name, options={})
+ label = options[:label]
+ label ||= to_step_name.to_s.humanize
+
+ name = options[:name]
+ name ||= to_step_name.to_s.parameterize
+
+ value = options[:value]
+ value ||= to_step_name.to_s.parameterize
+
+ if options
+ id = options[:id]
+ css_class = options[:class]
end
+
+ button = { :name => name, :value => value, :label => label }
+ button[:id] = id unless id.nil?
+ button[:class] = css_class unless css_class.nil?
+
+ { to_step_name => button }
end
end
module ControllerInstanceMethods
extend ActiveSupport::Concern
included do
before_filter :setup_wizard
end
+ def back_to_start
+ respond_to do |format|
+ format.json { }
+ end
+ end
+
private
def setup_wizard
wizard_def = self.class.instance_variable_get("@wizard_def")
- @ht_wizard = wizard_def.get_wizard(self)
+ @hat_trick_wizard ||= wizard_def.make_wizard_for(self)
+ Rails.logger.info "setup_wizard wizard instance: #{@hat_trick_wizard.object_id}"
+
+ config_callback = self.class.send(:configure_callback)
+ if config_callback.is_a?(Proc)
+ instance_exec(wizard_def.config, &config_callback)
+ end
+
if params.has_key?('_ht_meta')
step_name = params['_ht_meta']['step']
- @ht_wizard.current_step = step_name if step_name
+ end
+
+ # TODO: Setup the route that enables this in hat-trick automatically.
+ # Currently done manually in the app.
+ if params.has_key?('step')
+ step_name = params['step']
+ end
+
+ if step_name.present?
+ Rails.logger.info "Setting current step to: #{step_name}"
+ begin
+ @hat_trick_wizard.current_step = step_name
+ rescue StepNotFound => e
+ raise ActionController::RoutingError, e.message
+ end
end
end
end
end
end