hat-trick 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +5 -5
- data/app/assets/javascripts/hat-trick.js.coffee +254 -120
- data/app/views/hat_trick/_wizard_meta.html.erb +1 -1
- data/hat-trick.gemspec +3 -3
- data/lib/hat-trick.rb +1 -1
- data/lib/hat_trick/config.rb +17 -0
- data/lib/hat_trick/controller_helpers.rb +64 -0
- data/lib/hat_trick/controller_hooks.rb +20 -64
- data/lib/hat_trick/dsl.rb +86 -62
- data/lib/hat_trick/{rails_engine.rb → engine.rb} +1 -1
- data/lib/hat_trick/form_helper.rb +0 -4
- data/lib/hat_trick/model_methods.rb +30 -8
- data/lib/hat_trick/step_definition.rb +12 -12
- data/lib/hat_trick/version.rb +1 -1
- data/lib/hat_trick/wizard.rb +44 -27
- data/lib/hat_trick/wizard_definition.rb +2 -0
- data/lib/hat_trick/wizard_steps.rb +5 -2
- data/spec/lib/hat_trick/dsl_spec.rb +26 -0
- data/spec/lib/hat_trick/wizard_spec.rb +21 -19
- data/spec/spec_helper.rb +1 -9
- data/vendor/assets/javascripts/jquery.form.wizard.js +499 -438
- data/vendor/assets/javascripts/jquery.history.js +1 -0
- metadata +15 -12
- data/spec/lib/hat_trick/step_spec.rb +0 -9
- data/vendor/assets/javascripts/jquery.ba-bbq.js +0 -1137
@@ -1,8 +1,10 @@
|
|
1
1
|
require 'hat_trick/model_methods'
|
2
|
+
require 'hat_trick/controller_helpers'
|
2
3
|
|
3
4
|
module HatTrick
|
4
5
|
module ControllerHooks
|
5
6
|
extend ActiveSupport::Concern
|
7
|
+
include ControllerHelpers
|
6
8
|
|
7
9
|
included do
|
8
10
|
alias_method_chain :render, :hat_trick
|
@@ -10,12 +12,12 @@ module HatTrick
|
|
10
12
|
|
11
13
|
def self.def_action_method_aliases(action_methods)
|
12
14
|
action_methods.each do |meth|
|
13
|
-
Rails.logger.info "Aliasing #{meth}"
|
15
|
+
# Rails.logger.info "Aliasing #{meth}"
|
14
16
|
module_eval <<-RUBY_EVAL
|
15
17
|
def #{meth}_with_hat_trick(*args)
|
16
18
|
Rails.logger.info "#{meth}_with_hat_trick called"
|
17
19
|
#{meth}_hook(*args) if respond_to?("#{meth}_hook", :include_private)
|
18
|
-
common_hook(*args)
|
20
|
+
common_hook(*args) if respond_to?(:common_hook, :include_private)
|
19
21
|
#{meth}_without_hat_trick(*args)
|
20
22
|
end
|
21
23
|
private "#{meth}_with_hat_trick"
|
@@ -26,53 +28,6 @@ module HatTrick
|
|
26
28
|
|
27
29
|
private
|
28
30
|
|
29
|
-
def params_model_name
|
30
|
-
params.each do |k,v|
|
31
|
-
return class_name(k) if v.is_a?(Hash) && is_model?(k)
|
32
|
-
end
|
33
|
-
nil
|
34
|
-
end
|
35
|
-
|
36
|
-
def is_model?(model_name)
|
37
|
-
begin
|
38
|
-
class_name(model_name).constantize
|
39
|
-
rescue NameError
|
40
|
-
return false
|
41
|
-
end
|
42
|
-
true
|
43
|
-
end
|
44
|
-
|
45
|
-
def class_name(hash_key)
|
46
|
-
hash_key.to_s.camelize
|
47
|
-
end
|
48
|
-
|
49
|
-
def model_class
|
50
|
-
model_name = params_model_name
|
51
|
-
return nil if model_name.nil?
|
52
|
-
begin
|
53
|
-
model_class = params_model_name.constantize
|
54
|
-
rescue NameError
|
55
|
-
Rails.logger.error "Could not find model class #{params_model_name.camelize}"
|
56
|
-
nil
|
57
|
-
else
|
58
|
-
model_class
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def setup_validation_group_for(wizard_step)
|
63
|
-
klass = model_class
|
64
|
-
return if klass.nil?
|
65
|
-
step_name = wizard_step.name
|
66
|
-
validation_groups = ::ActiveRecord::Base.validation_group_classes[klass] || []
|
67
|
-
unless validation_groups.include?(step_name)
|
68
|
-
klass.validation_group(step_name, :fields => params.keys)
|
69
|
-
end
|
70
|
-
HatTrick::ModelMethods.set_current_validation_group_for(model_class, step_name)
|
71
|
-
unless klass.included_modules.include?(HatTrick::ModelMethods)
|
72
|
-
klass.send(:include, HatTrick::ModelMethods)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
31
|
def create_hook(*args)
|
77
32
|
setup_validation_group_for(ht_wizard.current_step)
|
78
33
|
end
|
@@ -81,13 +36,10 @@ module HatTrick
|
|
81
36
|
setup_validation_group_for(ht_wizard.current_step)
|
82
37
|
end
|
83
38
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
def render_with_hat_trick(*args)
|
89
|
-
if args.first.has_key?(:json)
|
90
|
-
model = args[0][:json]
|
39
|
+
def render_with_hat_trick(*args, &block)
|
40
|
+
rendered = args.first
|
41
|
+
if rendered && rendered.has_key?(:json)
|
42
|
+
model = rendered[:json]
|
91
43
|
ht_wizard.model = model
|
92
44
|
end
|
93
45
|
|
@@ -102,17 +54,21 @@ module HatTrick
|
|
102
54
|
:currentStep => ht_wizard.current_step,
|
103
55
|
}
|
104
56
|
|
105
|
-
|
106
|
-
|
57
|
+
include_data = ht_wizard.include_data
|
58
|
+
|
59
|
+
# this sets the gon data (JS hatTrick object) for the initial page load
|
60
|
+
gon.metadata = wizard_metadata
|
61
|
+
gon.data = include_data
|
62
|
+
gon.model = ht_wizard.model
|
107
63
|
|
108
|
-
|
109
|
-
|
110
|
-
args[0][:json] = { :
|
111
|
-
:
|
112
|
-
args[0][:json].merge!
|
64
|
+
# this sets the wizard metadata for subsequent AJAX requests
|
65
|
+
if ht_wizard.model && rendered.has_key?(:json)
|
66
|
+
args[0][:json] = { :model => ht_wizard.model,
|
67
|
+
:metadata => wizard_metadata }
|
68
|
+
args[0][:json].merge!( :data => include_data )
|
113
69
|
end
|
114
70
|
|
115
|
-
render_without_hat_trick(*args)
|
71
|
+
render_without_hat_trick(*args, &block)
|
116
72
|
end
|
117
73
|
end
|
118
74
|
end
|
data/lib/hat_trick/dsl.rb
CHANGED
@@ -1,75 +1,74 @@
|
|
1
1
|
require 'hat_trick/wizard_definition'
|
2
2
|
require 'hat_trick/controller_hooks'
|
3
|
+
require 'hat_trick/config'
|
3
4
|
|
4
5
|
module HatTrick
|
5
6
|
module DSL
|
6
7
|
extend ActiveSupport::Concern
|
7
8
|
|
8
|
-
|
9
|
-
def wizard(&block)
|
10
|
-
if block_given?
|
11
|
-
include HatTrick::DSL::ControllerInstanceMethods
|
12
|
-
include HatTrick::ControllerHooks
|
9
|
+
attr_accessor :ht_wizard, :configure_callback, :_ht_config
|
13
10
|
|
14
|
-
|
11
|
+
delegate :model, :previously_visited_step, :to => :ht_wizard
|
15
12
|
|
16
|
-
|
17
|
-
|
13
|
+
included do
|
14
|
+
alias_method_chain :initialize, :hat_trick
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
def initialize_with_hat_trick(*args)
|
18
|
+
@_ht_config = HatTrick::Config.new(self.class.wizard_def)
|
19
|
+
if configure_callback.is_a?(Proc)
|
20
|
+
ht_wizard.controller.instance_exec(@_ht_config, &configure_callback)
|
22
21
|
end
|
22
|
+
initialize_without_hat_trick(*args)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def next_step(name=nil)
|
26
|
+
if name.nil?
|
27
|
+
# getter
|
28
|
+
ht_wizard.next_step
|
29
|
+
else
|
30
|
+
# setter
|
31
|
+
step = ht_wizard.find_step(name)
|
32
|
+
# explicitly set steps should not be skipped
|
33
|
+
step.skipped = false
|
34
|
+
ht_wizard.current_step.next_step = step
|
30
35
|
end
|
36
|
+
end
|
31
37
|
|
32
|
-
|
38
|
+
def skip_this_step
|
39
|
+
ht_wizard.skip_step(ht_wizard.current_step)
|
40
|
+
end
|
33
41
|
|
34
|
-
|
42
|
+
module ClassMethods
|
43
|
+
attr_reader :wizard_def
|
35
44
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
45
|
+
def wizard(&block)
|
46
|
+
if block_given?
|
47
|
+
include HatTrick::DSL::ControllerInstanceMethods
|
48
|
+
include HatTrick::ControllerHooks
|
39
49
|
|
40
|
-
|
41
|
-
step_name = params['_ht_meta']['step']
|
42
|
-
@ht_wizard.current_step = step_name if step_name
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
50
|
+
@wizard_def = HatTrick::WizardDefinition.new
|
46
51
|
|
47
|
-
|
48
|
-
attr_reader :wizard_def
|
49
|
-
attr_accessor :wizard
|
52
|
+
yield
|
50
53
|
|
51
|
-
|
54
|
+
else
|
55
|
+
raise ArgumentError, "wizard called without a block"
|
56
|
+
end
|
57
|
+
end
|
52
58
|
|
53
|
-
def
|
54
|
-
|
59
|
+
def configure(&block)
|
60
|
+
raise "Must pass a block to configure" unless block_given?
|
61
|
+
@config_callback = block
|
55
62
|
end
|
56
63
|
|
57
64
|
def step(name, args={}, &block)
|
65
|
+
raise "step must be called from within a wizard block" unless wizard_def
|
58
66
|
wizard_def.add_step(name, args)
|
59
67
|
instance_eval &block if block_given?
|
60
68
|
end
|
61
69
|
|
62
|
-
def next_step(name=nil)
|
63
|
-
if name.nil?
|
64
|
-
wizard.next_step
|
65
|
-
else
|
66
|
-
raise "next_step should only be called from an after block" if wizard.nil?
|
67
|
-
step = wizard.find_step(name)
|
68
|
-
wizard.current_step.next_step = step
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
70
|
def repeat_step(name)
|
71
|
+
raise "repeat_step must be called from within a wizard block" unless wizard_def
|
73
72
|
repeated_step = wizard_def.find_step(name)
|
74
73
|
raise ArgumentError, "Couldn't find step named #{name}" unless repeated_step
|
75
74
|
new_step = repeated_step.dup
|
@@ -77,47 +76,72 @@ module HatTrick
|
|
77
76
|
new_step.fieldset = repeated_step.fieldset
|
78
77
|
# but use the current step's name
|
79
78
|
new_step.name = wizard_def.last_step.name
|
80
|
-
|
81
|
-
|
82
|
-
# rid of this wizard / wizard_def distinction
|
83
|
-
else
|
84
|
-
# replace the step we're in the middle of defining w/ new_step
|
85
|
-
wizard_def.replace_step(wizard_def.last_step, new_step)
|
86
|
-
end
|
79
|
+
# replace the step we're in the middle of defining w/ new_step
|
80
|
+
wizard_def.replace_step(wizard_def.last_step, new_step)
|
87
81
|
end
|
88
82
|
|
89
83
|
def skip_this_step
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
# can be explicitly jumped to, but won't be in the normal flow
|
95
|
-
wizard_def.last_step.skipped = true
|
96
|
-
end
|
84
|
+
# skip_this_step in wizard definition (class) context means the step
|
85
|
+
# can be explicitly jumped to, but won't be visited in the normal flow
|
86
|
+
raise "skip_this_step must be called from within a wizard block" unless wizard_def
|
87
|
+
wizard_def.last_step.skipped = true
|
97
88
|
end
|
98
89
|
|
99
90
|
def button_to(name, options=nil)
|
100
|
-
|
101
|
-
raise "button_to not yet supported in before/after blocks"
|
102
|
-
end
|
91
|
+
raise "button_to must be called from within a wizard block" unless wizard_def
|
103
92
|
label = options[:label] if options
|
104
93
|
label ||= name.to_s.humanize
|
94
|
+
|
95
|
+
id = options[:id] if options
|
96
|
+
|
105
97
|
step = wizard_def.last_step
|
106
|
-
|
98
|
+
button = { :label => label }
|
99
|
+
button[:id] = id unless id.nil?
|
100
|
+
step.buttons = step.buttons.merge(name => button)
|
107
101
|
end
|
108
102
|
|
109
103
|
def before(&block)
|
104
|
+
raise "before must be called from within a wizard block" unless wizard_def
|
110
105
|
wizard_def.last_step.before_callback = block
|
111
106
|
end
|
112
107
|
|
113
108
|
def after(&block)
|
109
|
+
raise "after must be called from within a wizard block" unless wizard_def
|
114
110
|
wizard_def.last_step.after_callback = block
|
115
111
|
end
|
116
112
|
|
117
113
|
def include_data(key, &block)
|
114
|
+
raise "include_data must be called from within a wizard block" unless wizard_def
|
118
115
|
wizard_def.last_step.include_data = { key.to_sym => block }
|
119
116
|
end
|
117
|
+
|
118
|
+
def set_contents(&block)
|
119
|
+
raise "set_contents must be called from within a wizard block" unless wizard_def
|
120
|
+
current_step_name = wizard_def.last_step.to_sym
|
121
|
+
include_data "hat_trick_step_contents" do |wiz, model|
|
122
|
+
{ current_step_name => instance_exec(wiz, model, &block) }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
module ControllerInstanceMethods
|
128
|
+
extend ActiveSupport::Concern
|
129
|
+
|
130
|
+
included do
|
131
|
+
before_filter :setup_wizard
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def setup_wizard
|
137
|
+
wizard_def = self.class.instance_variable_get("@wizard_def")
|
138
|
+
@ht_wizard = wizard_def.get_wizard(self)
|
139
|
+
|
140
|
+
if params.has_key?('_ht_meta')
|
141
|
+
step_name = params['_ht_meta']['step']
|
142
|
+
@ht_wizard.current_step = step_name if step_name
|
143
|
+
end
|
144
|
+
end
|
120
145
|
end
|
121
146
|
end
|
122
147
|
end
|
123
|
-
|
@@ -7,10 +7,6 @@ module HatTrick
|
|
7
7
|
wizard = controller.send(:ht_wizard)
|
8
8
|
wizard.start unless wizard.started?
|
9
9
|
|
10
|
-
# Do we still need these 2 lines?
|
11
|
-
wizard.model = record
|
12
|
-
controller.gon.form_model = record
|
13
|
-
|
14
10
|
options[:url] = wizard.current_form_url
|
15
11
|
options[:method] = wizard.current_form_method.to_sym
|
16
12
|
|
@@ -1,24 +1,46 @@
|
|
1
1
|
module HatTrick
|
2
2
|
module ModelMethods
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
mattr_accessor :
|
4
|
+
mattr_accessor :validation_groups
|
5
|
+
|
6
|
+
attr_accessor :_dummy # so the dummy field will have something to set
|
5
7
|
|
6
8
|
included do
|
7
|
-
alias_method_chain :
|
9
|
+
alias_method_chain :perform_validations, :hat_trick if instance_methods.include?(:perform_validations)
|
10
|
+
alias_method_chain :as_json, :model_name if instance_methods.include?(:as_json)
|
8
11
|
end
|
9
12
|
|
10
13
|
def self.set_current_validation_group_for(klass, validation_group_name)
|
11
|
-
self.
|
12
|
-
|
14
|
+
self.validation_groups ||= {}
|
15
|
+
validation_groups[klass.to_s.underscore] = validation_group_name
|
13
16
|
end
|
14
17
|
|
15
18
|
def self.current_validation_group_for(klass)
|
16
|
-
|
19
|
+
return nil unless validation_groups
|
20
|
+
validation_groups[klass.to_s.underscore]
|
21
|
+
end
|
22
|
+
|
23
|
+
def perform_validations_with_hat_trick(*args, &block)
|
24
|
+
enable_current_validation_group
|
25
|
+
perform_validations_without_hat_trick(*args, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def as_json_with_model_name(*args, &block)
|
29
|
+
json = as_json_without_model_name(*args, &block)
|
30
|
+
json.merge! :__name__ => self.class.to_s.underscore if json.respond_to?(:merge!)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# don't call this method 'current_validation_group', it conflicts with
|
36
|
+
# the gem
|
37
|
+
def current_step_validation_group
|
38
|
+
HatTrick::ModelMethods.current_validation_group_for(self.class)
|
17
39
|
end
|
18
40
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
41
|
+
def enable_current_validation_group
|
42
|
+
validation_group = current_step_validation_group
|
43
|
+
enable_validation_group validation_group if validation_group
|
22
44
|
end
|
23
45
|
end
|
24
46
|
end
|
@@ -17,7 +17,7 @@ module HatTrick
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize_copy(source)
|
20
|
-
@callbacks =
|
20
|
+
@callbacks = {}
|
21
21
|
@buttons = source.buttons.dup
|
22
22
|
@skipped = false
|
23
23
|
@repeat_of = source
|
@@ -74,27 +74,27 @@ module HatTrick
|
|
74
74
|
@include_data_key = hash.keys.first
|
75
75
|
end
|
76
76
|
|
77
|
-
def run_before_callback(context,
|
78
|
-
run_callback(:before, context,
|
77
|
+
def run_before_callback(context, model)
|
78
|
+
run_callback(:before, context, model)
|
79
79
|
end
|
80
80
|
|
81
|
-
def run_include_data_callback(context,
|
82
|
-
run_callback(:include_data, context,
|
81
|
+
def run_include_data_callback(context, model)
|
82
|
+
run_callback(:include_data, context, model)
|
83
83
|
end
|
84
84
|
|
85
|
-
def run_after_callback(context,
|
86
|
-
run_callback(:after, context,
|
85
|
+
def run_after_callback(context, model)
|
86
|
+
run_callback(:after, context, model)
|
87
87
|
end
|
88
88
|
|
89
89
|
protected
|
90
90
|
|
91
|
-
def run_callback(type, context,
|
91
|
+
def run_callback(type, context, model)
|
92
92
|
callback = callbacks[type.to_sym]
|
93
93
|
if callback && callback.is_a?(Proc)
|
94
|
-
if callback.arity >
|
95
|
-
|
96
|
-
|
97
|
-
|
94
|
+
if callback.arity > 0
|
95
|
+
unless model.is_a?(ActiveModel::Errors)
|
96
|
+
context.instance_exec model, &callback
|
97
|
+
end
|
98
98
|
else
|
99
99
|
context.instance_eval &callback
|
100
100
|
end
|
data/lib/hat_trick/version.rb
CHANGED
data/lib/hat_trick/wizard.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
require 'hat_trick/controller_hooks'
|
2
2
|
require 'hat_trick/wizard_steps'
|
3
|
+
require 'hat_trick/dsl'
|
3
4
|
|
4
5
|
module HatTrick
|
5
6
|
class Wizard
|
6
7
|
include WizardSteps
|
7
8
|
|
8
9
|
attr_accessor :controller, :model
|
9
|
-
attr_reader :current_step, :wizard_def, :
|
10
|
+
attr_reader :current_step, :wizard_def, :steps
|
10
11
|
|
11
12
|
def initialize(wizard_def)
|
12
13
|
@wizard_def = wizard_def
|
13
|
-
@wizard_dsl_context = DSL::WizardContext.new(@wizard_def)
|
14
|
-
@wizard_dsl_context.wizard = self
|
15
14
|
@steps = @wizard_def.steps.map { |s| HatTrick::Step.new(s, self) }
|
16
15
|
end
|
17
16
|
|
@@ -19,6 +18,13 @@ module HatTrick
|
|
19
18
|
@controller = new_controller
|
20
19
|
end
|
21
20
|
|
21
|
+
def model=(new_model)
|
22
|
+
@model = new_model
|
23
|
+
unless @model.class.included_modules.include?(HatTrick::ModelMethods)
|
24
|
+
@model.class.send(:include, HatTrick::ModelMethods)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
22
28
|
def current_step=(_step)
|
23
29
|
raise "Don't set current_step to nil" if _step.nil?
|
24
30
|
step = find_step(_step)
|
@@ -27,7 +33,11 @@ module HatTrick
|
|
27
33
|
end
|
28
34
|
|
29
35
|
def session
|
30
|
-
|
36
|
+
if controller.nil?
|
37
|
+
fake_session
|
38
|
+
else
|
39
|
+
controller.session
|
40
|
+
end
|
31
41
|
end
|
32
42
|
|
33
43
|
def model_created?
|
@@ -43,11 +53,13 @@ module HatTrick
|
|
43
53
|
end
|
44
54
|
|
45
55
|
def create_url
|
56
|
+
wizard_def.configured_create_url or
|
46
57
|
controller.url_for(:controller => controller.controller_name,
|
47
58
|
:action => 'create', :only_path => true)
|
48
59
|
end
|
49
60
|
|
50
61
|
def update_url
|
62
|
+
wizard_def.configured_update_url or
|
51
63
|
if model_created?
|
52
64
|
controller.url_for(:controller => controller.controller_name,
|
53
65
|
:action => 'update', :id => model,
|
@@ -80,28 +92,16 @@ module HatTrick
|
|
80
92
|
|
81
93
|
def start
|
82
94
|
session["hat-trick.steps_visited"] = []
|
83
|
-
self.current_step
|
95
|
+
self.current_step ||= first_step
|
84
96
|
run_before_callback
|
85
97
|
end
|
86
98
|
|
87
|
-
def finish
|
88
|
-
# Do something here
|
89
|
-
# Such as: Force the wizard to display the "done" page
|
90
|
-
Rails.logger.info "WIZARD FINISHED!"
|
91
|
-
end
|
92
|
-
|
93
99
|
def run_before_callback(step=current_step)
|
94
|
-
step.run_before_callback(controller,
|
100
|
+
step.run_before_callback(controller, model)
|
95
101
|
end
|
96
102
|
|
97
103
|
def run_after_callback(step=current_step)
|
98
|
-
step.run_after_callback(controller,
|
99
|
-
end
|
100
|
-
|
101
|
-
def advance_step_with_debugger
|
102
|
-
require 'ruby-debug'
|
103
|
-
debugger
|
104
|
-
advance_step
|
104
|
+
step.run_after_callback(controller, model)
|
105
105
|
end
|
106
106
|
|
107
107
|
def advance_step(next_step_name=nil)
|
@@ -114,7 +114,7 @@ module HatTrick
|
|
114
114
|
|
115
115
|
# finish if we're on the last step
|
116
116
|
if current_step == last_step && !requested_next_step
|
117
|
-
|
117
|
+
raise "Tried to advance beyond the last step of the wizard"
|
118
118
|
else # we're not on the last step
|
119
119
|
if requested_next_step
|
120
120
|
Rails.logger.info "Force advancing to step: #{requested_next_step}"
|
@@ -135,10 +135,20 @@ module HatTrick
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def include_data
|
138
|
-
return {}
|
139
|
-
inc_data =
|
140
|
-
|
141
|
-
|
138
|
+
return {} if model.nil?
|
139
|
+
inc_data = {}
|
140
|
+
include_data_steps = steps_before(current_step) << current_step
|
141
|
+
include_data_steps.each do |step|
|
142
|
+
step_data = step.run_include_data_callback(controller, model)
|
143
|
+
next if step_data.nil? || !step_data.respond_to?(:as_json)
|
144
|
+
step_key = step.include_data_key.to_s.camelize(:lower)
|
145
|
+
begin
|
146
|
+
inc_data[step_key] = camelize_hash_keys(step_data)
|
147
|
+
rescue NoMethodError => e
|
148
|
+
Rails.logger.error "Unable to serialize data for step #{step}: #{e}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
inc_data
|
142
152
|
end
|
143
153
|
|
144
154
|
def alias_action_methods
|
@@ -155,6 +165,10 @@ module HatTrick
|
|
155
165
|
|
156
166
|
private
|
157
167
|
|
168
|
+
def fake_session
|
169
|
+
@fake_session ||= {}
|
170
|
+
end
|
171
|
+
|
158
172
|
def find_next_step
|
159
173
|
find_step(current_step.next_step) or find_step_after(current_step)
|
160
174
|
end
|
@@ -165,10 +179,13 @@ module HatTrick
|
|
165
179
|
end
|
166
180
|
|
167
181
|
def camelize_hash_keys(_hash)
|
168
|
-
return nil if _hash.nil?
|
169
182
|
hash = {}
|
170
|
-
_hash.each
|
171
|
-
|
183
|
+
if _hash.respond_to?(:each)
|
184
|
+
_hash.each do |k,v|
|
185
|
+
hash[k.to_s.camelize(:lower)] = v
|
186
|
+
end
|
187
|
+
else
|
188
|
+
hash = _hash
|
172
189
|
end
|
173
190
|
hash
|
174
191
|
end
|
@@ -26,7 +26,9 @@ module HatTrick
|
|
26
26
|
def steps_after(_step)
|
27
27
|
step = find_step(_step)
|
28
28
|
return [] unless step
|
29
|
-
|
29
|
+
step_index = steps.index(step)
|
30
|
+
max_index = steps.count - 1
|
31
|
+
after_index = step_index < max_index ? step_index + 1 : step_index
|
30
32
|
steps[after_index .. -1]
|
31
33
|
end
|
32
34
|
|
@@ -37,7 +39,8 @@ module HatTrick
|
|
37
39
|
def steps_before(_step)
|
38
40
|
step = find_step(_step)
|
39
41
|
return [] unless step
|
40
|
-
|
42
|
+
step_index = steps.index(step)
|
43
|
+
before_index = step_index > 0 ? step_index - 1 : step_index
|
41
44
|
steps[0 .. before_index]
|
42
45
|
end
|
43
46
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# will automatically get HatTrick::DSL included
|
4
|
+
class FakeController < ActionController::Base; end
|
5
|
+
|
6
|
+
describe HatTrick::DSL do
|
7
|
+
let(:controller_class) { FakeController }
|
8
|
+
|
9
|
+
# save some typing
|
10
|
+
def dsl(&block)
|
11
|
+
controller_class.instance_eval &block
|
12
|
+
end
|
13
|
+
|
14
|
+
describe HatTrick::DSL::ClassMethods do
|
15
|
+
describe "#step" do
|
16
|
+
it "should call Wizard#add_step" do
|
17
|
+
HatTrick::WizardDefinition.any_instance.expects(:add_step).with(:foo, {})
|
18
|
+
dsl do
|
19
|
+
wizard do
|
20
|
+
step :foo
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|