hat-trick 0.1.2 → 0.1.3
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/.gitignore +1 -0
- data/Changelog +17 -3
- data/README.md +44 -19
- data/app/assets/javascripts/hat-trick.js.coffee +214 -123
- data/lib/hat-trick.rb +0 -2
- data/lib/hat_trick/config.rb +10 -11
- data/lib/hat_trick/controller_helpers.rb +18 -4
- data/lib/hat_trick/controller_hooks.rb +37 -23
- data/lib/hat_trick/dsl.rb +144 -50
- data/lib/hat_trick/engine.rb +6 -0
- data/lib/hat_trick/form_helper.rb +1 -1
- data/lib/hat_trick/model_methods.rb +14 -3
- data/lib/hat_trick/step.rb +24 -11
- data/lib/hat_trick/step_definition.rb +162 -36
- data/lib/hat_trick/version.rb +1 -1
- data/lib/hat_trick/wizard.rb +105 -46
- data/lib/hat_trick/wizard_definition.rb +18 -9
- data/lib/hat_trick/wizard_steps.rb +12 -3
- data/spec/lib/hat_trick/dsl_spec.rb +11 -10
- data/spec/lib/hat_trick/step_definition_spec.rb +106 -0
- data/spec/lib/hat_trick/wizard_definition_spec.rb +18 -9
- data/spec/lib/hat_trick/wizard_spec.rb +22 -17
- data/spec/spec_helper.rb +6 -0
- data/vendor/assets/javascripts/array.filter.js +22 -0
- data/vendor/assets/javascripts/history.html4.js +658 -0
- data/vendor/assets/javascripts/history.js +1991 -0
- data/vendor/assets/javascripts/jquery.form.wizard.js +162 -145
- data/vendor/assets/javascripts/jquery.history.js +77 -1
- data/vendor/assets/javascripts/json.js +480 -0
- metadata +10 -4
@@ -28,7 +28,7 @@ module HatTrick
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def model_class
|
31
|
-
return
|
31
|
+
return hat_trick_wizard.model.class if hat_trick_wizard.model
|
32
32
|
|
33
33
|
# if that didn't work, try to grab it from the params hash
|
34
34
|
model_name = params_model_name
|
@@ -46,10 +46,21 @@ module HatTrick
|
|
46
46
|
|
47
47
|
def setup_validation_group_for(wizard_step)
|
48
48
|
klass = model_class
|
49
|
-
|
49
|
+
if klass.nil?
|
50
|
+
Rails.logger.warn "model class was nil when setting up validation group for #{wizard_step}"
|
51
|
+
return
|
52
|
+
end
|
50
53
|
step_name = wizard_step.name
|
51
54
|
validation_groups = ::ActiveRecord::Base.validation_group_classes[klass] || []
|
52
|
-
|
55
|
+
dynamic_group_exists = HatTrick::ModelMethods.dynamic_validation_groups.include?(step_name)
|
56
|
+
static_validation_group_exists = validation_groups.include?(step_name) && !dynamic_group_exists
|
57
|
+
dynamic_validation_group = false
|
58
|
+
|
59
|
+
if static_validation_group_exists
|
60
|
+
Rails.logger.info "Not creating dynamic validation group for #{step_name} because a static one exists"
|
61
|
+
else
|
62
|
+
Rails.logger.info "Creating a dynamic validation group for #{step_name}"
|
63
|
+
dynamic_validation_group = true
|
53
64
|
validation_fields = params.keys # TODO: Try it without these (so only the model keys below)
|
54
65
|
model = model_key
|
55
66
|
if model
|
@@ -58,7 +69,10 @@ module HatTrick
|
|
58
69
|
validation_fields = validation_fields.map(&:to_sym)
|
59
70
|
klass.validation_group(step_name, :fields => validation_fields)
|
60
71
|
end
|
61
|
-
|
72
|
+
Rails.logger.info "Setting current validation group for model class #{model_class} to #{step_name}"
|
73
|
+
HatTrick::ModelMethods.set_current_validation_group_for(model_class,
|
74
|
+
step_name,
|
75
|
+
dynamic_validation_group)
|
62
76
|
end
|
63
77
|
end
|
64
78
|
end
|
@@ -12,62 +12,76 @@ module HatTrick
|
|
12
12
|
|
13
13
|
def self.def_action_method_aliases(action_methods)
|
14
14
|
action_methods.each do |meth|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
15
|
+
unless respond_to?(:"#{meth}_with_hat_trick")
|
16
|
+
Rails.logger.info "Defining #{meth}_with_hat_trick"
|
17
|
+
module_eval <<-RUBY_EVAL
|
18
|
+
def #{meth}_with_hat_trick(*args)
|
19
|
+
Rails.logger.info "#{meth}_with_hat_trick called"
|
20
|
+
if respond_to?("#{meth}_hook", :include_private)
|
21
|
+
#{meth}_hook(*args)
|
22
|
+
end
|
23
|
+
common_hook(*args) if respond_to?(:common_hook, :include_private)
|
24
|
+
#{meth}_without_hat_trick(*args)
|
25
|
+
end
|
26
|
+
private "#{meth}_with_hat_trick"
|
27
|
+
RUBY_EVAL
|
28
|
+
end
|
25
29
|
end
|
26
30
|
true
|
27
31
|
end
|
28
32
|
|
29
33
|
private
|
30
34
|
|
35
|
+
def common_hook(*args)
|
36
|
+
Rails.logger.info "common_hook wizard instance: #{hat_trick_wizard.object_id}"
|
37
|
+
end
|
38
|
+
|
31
39
|
def create_hook(*args)
|
32
|
-
setup_validation_group_for(
|
40
|
+
setup_validation_group_for(hat_trick_wizard.current_step)
|
33
41
|
end
|
34
42
|
|
35
43
|
def update_hook(*args)
|
36
|
-
setup_validation_group_for(
|
44
|
+
setup_validation_group_for(hat_trick_wizard.current_step)
|
37
45
|
end
|
38
46
|
|
39
47
|
def render_with_hat_trick(*args, &block)
|
40
48
|
rendered = args.first
|
41
49
|
if rendered && rendered.has_key?(:json)
|
42
|
-
model = rendered[:json]
|
43
|
-
|
50
|
+
hat_trick_wizard.model = rendered[:json]
|
51
|
+
else
|
52
|
+
Rails.logger.warn "No model found in render args #{args.inspect}; model is #{hat_trick_wizard.model.inspect}"
|
44
53
|
end
|
45
54
|
|
46
55
|
if params.has_key?('_ht_meta')
|
47
|
-
next_step = params['
|
48
|
-
|
56
|
+
next_step = params['_ht_step_link']
|
57
|
+
hat_trick_wizard.advance_step(next_step)
|
49
58
|
end
|
50
59
|
|
51
60
|
wizard_metadata = {
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
61
|
+
:externalRedirectURL => hat_trick_wizard.external_redirect_url,
|
62
|
+
:url => hat_trick_wizard.current_form_url,
|
63
|
+
:method => hat_trick_wizard.current_form_method,
|
64
|
+
:currentStep => hat_trick_wizard.current_step,
|
65
|
+
:percentComplete => hat_trick_wizard.percent_complete,
|
55
66
|
}
|
56
67
|
|
57
|
-
include_data =
|
68
|
+
include_data = hat_trick_wizard.include_data
|
58
69
|
|
59
70
|
# this sets the gon data (JS hatTrick object) for the initial page load
|
60
71
|
gon.metadata = wizard_metadata
|
61
72
|
gon.data = include_data
|
62
|
-
gon.model =
|
73
|
+
gon.model = hat_trick_wizard.model
|
63
74
|
|
64
75
|
# this sets the wizard metadata for subsequent AJAX requests
|
65
|
-
if
|
66
|
-
args[0][:json] = { :model =>
|
76
|
+
if hat_trick_wizard.model && rendered.has_key?(:json)
|
77
|
+
args[0][:json] = { :model => hat_trick_wizard.model,
|
67
78
|
:metadata => wizard_metadata }
|
68
79
|
args[0][:json].merge!( :data => include_data )
|
69
80
|
end
|
70
81
|
|
82
|
+
# unset redirects for subsequent steps
|
83
|
+
hat_trick_wizard.external_redirect_url = nil
|
84
|
+
|
71
85
|
render_without_hat_trick(*args, &block)
|
72
86
|
end
|
73
87
|
end
|
data/lib/hat_trick/dsl.rb
CHANGED
@@ -6,37 +6,66 @@ module HatTrick
|
|
6
6
|
module DSL
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :hat_trick_wizard
|
10
10
|
|
11
|
-
delegate :model, :previously_visited_step, :to => :
|
12
|
-
|
13
|
-
included do
|
14
|
-
alias_method_chain :initialize, :hat_trick
|
15
|
-
end
|
16
|
-
|
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)
|
21
|
-
end
|
22
|
-
initialize_without_hat_trick(*args)
|
23
|
-
end
|
11
|
+
delegate :model, :previously_visited_step, :to => :hat_trick_wizard
|
24
12
|
|
25
13
|
def next_step(name=nil)
|
26
14
|
if name.nil?
|
27
15
|
# getter
|
28
|
-
|
16
|
+
hat_trick_wizard.next_step
|
29
17
|
else
|
30
18
|
# setter
|
31
|
-
step =
|
19
|
+
step = hat_trick_wizard.find_step(name)
|
32
20
|
# explicitly set steps should not be skipped
|
33
21
|
step.skipped = false
|
34
|
-
|
22
|
+
hat_trick_wizard.current_step.next_step = step
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def previously_visited_step_name
|
27
|
+
if previously_visited_step.nil?
|
28
|
+
''
|
29
|
+
else
|
30
|
+
previously_visited_step.name
|
35
31
|
end
|
36
32
|
end
|
37
33
|
|
38
34
|
def skip_this_step
|
39
|
-
|
35
|
+
hat_trick_wizard.skip_step(hat_trick_wizard.current_step)
|
36
|
+
end
|
37
|
+
|
38
|
+
def button_to(step_name, options={})
|
39
|
+
button = self.class.send(:create_button_to, step_name, options)
|
40
|
+
hat_trick_wizard.current_step.add_button button
|
41
|
+
end
|
42
|
+
|
43
|
+
def remaining_step_count
|
44
|
+
hat_trick_wizard.steps_after_current
|
45
|
+
end
|
46
|
+
|
47
|
+
def adjust_remaining_step_count_by(diff)
|
48
|
+
hat_trick_wizard.steps_remaining += diff
|
49
|
+
end
|
50
|
+
|
51
|
+
def change_remaining_step_count_to(count)
|
52
|
+
hat_trick_wizard.steps_remaining = count
|
53
|
+
end
|
54
|
+
|
55
|
+
def total_step_count
|
56
|
+
hat_trick_wizard.total_step_count
|
57
|
+
end
|
58
|
+
|
59
|
+
def reset_step_count
|
60
|
+
hat_trick_wizard.override_step_count = nil
|
61
|
+
end
|
62
|
+
|
63
|
+
def redirect_to_step(step_name)
|
64
|
+
hat_trick_wizard.redirect_to_step step_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def redirect_to_external_url(url)
|
68
|
+
hat_trick_wizard.external_redirect_url = url
|
40
69
|
end
|
41
70
|
|
42
71
|
module ClassMethods
|
@@ -47,7 +76,10 @@ module HatTrick
|
|
47
76
|
include HatTrick::DSL::ControllerInstanceMethods
|
48
77
|
include HatTrick::ControllerHooks
|
49
78
|
|
50
|
-
|
79
|
+
::ActiveRecord::Base.send(:include, HatTrick::ModelMethods)
|
80
|
+
|
81
|
+
config = HatTrick::Config.new
|
82
|
+
@wizard_def = HatTrick::WizardDefinition.new(config)
|
51
83
|
|
52
84
|
yield
|
53
85
|
|
@@ -58,7 +90,15 @@ module HatTrick
|
|
58
90
|
|
59
91
|
def configure(&block)
|
60
92
|
raise "Must pass a block to configure" unless block_given?
|
61
|
-
|
93
|
+
self.configure_callback = block
|
94
|
+
end
|
95
|
+
|
96
|
+
def button_label(type, label)
|
97
|
+
wizard_def.config.send("#{type}_button_label=", label)
|
98
|
+
end
|
99
|
+
|
100
|
+
def button_label_i18n_key(type, i18n_key)
|
101
|
+
wizard_def.config.send("#{type}_button_label_i18n_key=", i18n_key)
|
62
102
|
end
|
63
103
|
|
64
104
|
def step(name, args={}, &block)
|
@@ -67,19 +107,6 @@ module HatTrick
|
|
67
107
|
instance_eval &block if block_given?
|
68
108
|
end
|
69
109
|
|
70
|
-
def repeat_step(name)
|
71
|
-
raise "repeat_step must be called from within a wizard block" unless wizard_def
|
72
|
-
repeated_step = wizard_def.find_step(name)
|
73
|
-
raise ArgumentError, "Couldn't find step named #{name}" unless repeated_step
|
74
|
-
new_step = repeated_step.dup
|
75
|
-
# use the repeated step's fieldset id
|
76
|
-
new_step.fieldset = repeated_step.fieldset
|
77
|
-
# but use the current step's name
|
78
|
-
new_step.name = wizard_def.last_step.name
|
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)
|
81
|
-
end
|
82
|
-
|
83
110
|
def skip_this_step
|
84
111
|
# skip_this_step in wizard definition (class) context means the step
|
85
112
|
# can be explicitly jumped to, but won't be visited in the normal flow
|
@@ -87,27 +114,38 @@ module HatTrick
|
|
87
114
|
wizard_def.last_step.skipped = true
|
88
115
|
end
|
89
116
|
|
90
|
-
def
|
91
|
-
raise "
|
92
|
-
|
93
|
-
|
117
|
+
def last_step
|
118
|
+
raise "skip_this_step must be called from within a wizard block" unless wizard_def
|
119
|
+
wizard_def.last_step.last = true
|
120
|
+
end
|
94
121
|
|
95
|
-
|
122
|
+
def button_to(step_name, options={})
|
123
|
+
raise "button_to must be called from within a wizard block" unless wizard_def
|
124
|
+
wizard_def.last_step.add_button create_button_to(step_name, options)
|
125
|
+
end
|
96
126
|
|
127
|
+
def hide_button(button_type)
|
128
|
+
raise "before must be called from within a wizard block" unless wizard_def
|
97
129
|
step = wizard_def.last_step
|
98
|
-
|
99
|
-
button[:id] = id unless id.nil?
|
100
|
-
step.buttons = step.buttons.merge(name => button)
|
130
|
+
step.delete_button button_type
|
101
131
|
end
|
102
132
|
|
103
|
-
def before(&block)
|
133
|
+
def before(scope=:current_step, &block)
|
104
134
|
raise "before must be called from within a wizard block" unless wizard_def
|
105
|
-
|
135
|
+
if scope == :each
|
136
|
+
wizard_def.before_callback_for_all_steps = block
|
137
|
+
else
|
138
|
+
wizard_def.last_step.before_callback = block
|
139
|
+
end
|
106
140
|
end
|
107
141
|
|
108
|
-
def after(&block)
|
142
|
+
def after(scope=:current_step, &block)
|
109
143
|
raise "after must be called from within a wizard block" unless wizard_def
|
110
|
-
|
144
|
+
if scope == :each
|
145
|
+
wizard_def.after_callback_for_all_steps = block
|
146
|
+
else
|
147
|
+
wizard_def.last_step.after_callback = block
|
148
|
+
end
|
111
149
|
end
|
112
150
|
|
113
151
|
def include_data(key, &block)
|
@@ -117,10 +155,39 @@ module HatTrick
|
|
117
155
|
|
118
156
|
def set_contents(&block)
|
119
157
|
raise "set_contents must be called from within a wizard block" unless wizard_def
|
120
|
-
|
121
|
-
|
122
|
-
|
158
|
+
wizard_def.last_step.step_contents_callback = block
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
def configure_callback
|
164
|
+
@configure_callback
|
165
|
+
end
|
166
|
+
|
167
|
+
def configure_callback=(block)
|
168
|
+
@configure_callback = block
|
169
|
+
end
|
170
|
+
|
171
|
+
def create_button_to(to_step_name, options={})
|
172
|
+
label = options[:label]
|
173
|
+
label ||= to_step_name.to_s.humanize
|
174
|
+
|
175
|
+
name = options[:name]
|
176
|
+
name ||= to_step_name.to_s.parameterize
|
177
|
+
|
178
|
+
value = options[:value]
|
179
|
+
value ||= to_step_name.to_s.parameterize
|
180
|
+
|
181
|
+
if options
|
182
|
+
id = options[:id]
|
183
|
+
css_class = options[:class]
|
123
184
|
end
|
185
|
+
|
186
|
+
button = { :name => name, :value => value, :label => label }
|
187
|
+
button[:id] = id unless id.nil?
|
188
|
+
button[:class] = css_class unless css_class.nil?
|
189
|
+
|
190
|
+
{ to_step_name => button }
|
124
191
|
end
|
125
192
|
end
|
126
193
|
|
@@ -131,15 +198,42 @@ module HatTrick
|
|
131
198
|
before_filter :setup_wizard
|
132
199
|
end
|
133
200
|
|
201
|
+
def back_to_start
|
202
|
+
respond_to do |format|
|
203
|
+
format.json { }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
134
207
|
private
|
135
208
|
|
136
209
|
def setup_wizard
|
137
210
|
wizard_def = self.class.instance_variable_get("@wizard_def")
|
138
|
-
@
|
211
|
+
@hat_trick_wizard ||= wizard_def.make_wizard_for(self)
|
212
|
+
|
213
|
+
Rails.logger.info "setup_wizard wizard instance: #{@hat_trick_wizard.object_id}"
|
214
|
+
|
215
|
+
config_callback = self.class.send(:configure_callback)
|
216
|
+
if config_callback.is_a?(Proc)
|
217
|
+
instance_exec(wizard_def.config, &config_callback)
|
218
|
+
end
|
139
219
|
|
140
220
|
if params.has_key?('_ht_meta')
|
141
221
|
step_name = params['_ht_meta']['step']
|
142
|
-
|
222
|
+
end
|
223
|
+
|
224
|
+
# TODO: Setup the route that enables this in hat-trick automatically.
|
225
|
+
# Currently done manually in the app.
|
226
|
+
if params.has_key?('step')
|
227
|
+
step_name = params['step']
|
228
|
+
end
|
229
|
+
|
230
|
+
if step_name.present?
|
231
|
+
Rails.logger.info "Setting current step to: #{step_name}"
|
232
|
+
begin
|
233
|
+
@hat_trick_wizard.current_step = step_name
|
234
|
+
rescue StepNotFound => e
|
235
|
+
raise ActionController::RoutingError, e.message
|
236
|
+
end
|
143
237
|
end
|
144
238
|
end
|
145
239
|
end
|
data/lib/hat_trick/engine.rb
CHANGED
@@ -4,6 +4,12 @@ module HatTrick
|
|
4
4
|
class Engine < ::Rails::Engine
|
5
5
|
# just defining this causes Rails to look for assets inside this gem
|
6
6
|
|
7
|
+
initializer 'hat-trick.dsl' do
|
8
|
+
ActiveSupport.on_load(:action_controller) do
|
9
|
+
include HatTrick::DSL
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
initializer 'hat-trick.form_helpers' do
|
8
14
|
ActiveSupport.on_load(:action_view) do
|
9
15
|
include HatTrick::FormHelper
|
@@ -2,6 +2,7 @@ module HatTrick
|
|
2
2
|
module ModelMethods
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
mattr_accessor :validation_groups
|
5
|
+
mattr_accessor :dynamic_validation_groups
|
5
6
|
|
6
7
|
attr_accessor :_dummy # so the dummy field will have something to set
|
7
8
|
|
@@ -10,9 +11,14 @@ module HatTrick
|
|
10
11
|
alias_method_chain :as_json, :model_name if instance_methods.include?(:as_json)
|
11
12
|
end
|
12
13
|
|
13
|
-
def self.
|
14
|
+
def self.dynamic_validation_groups
|
15
|
+
@dynamic_validation_groups ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.set_current_validation_group_for(klass, validation_group_name, dynamic)
|
14
19
|
self.validation_groups ||= {}
|
15
20
|
validation_groups[klass.to_s.underscore] = validation_group_name
|
21
|
+
dynamic_validation_groups << validation_group_name if dynamic
|
16
22
|
end
|
17
23
|
|
18
24
|
def self.current_validation_group_for(klass)
|
@@ -33,14 +39,19 @@ module HatTrick
|
|
33
39
|
private
|
34
40
|
|
35
41
|
# don't call this method 'current_validation_group', it conflicts with
|
36
|
-
# the gem
|
42
|
+
# the validation_group gem
|
37
43
|
def current_step_validation_group
|
38
44
|
HatTrick::ModelMethods.current_validation_group_for(self.class)
|
39
45
|
end
|
40
46
|
|
41
47
|
def enable_current_validation_group
|
42
48
|
validation_group = current_step_validation_group
|
43
|
-
|
49
|
+
if validation_group
|
50
|
+
Rails.logger.info "Enabling validation group #{validation_group}"
|
51
|
+
enable_validation_group validation_group
|
52
|
+
else
|
53
|
+
Rails.logger.info "NOT enabling a validation group"
|
54
|
+
end
|
44
55
|
end
|
45
56
|
end
|
46
57
|
end
|
data/lib/hat_trick/step.rb
CHANGED
@@ -3,12 +3,16 @@ require 'hat_trick/step_definition'
|
|
3
3
|
module HatTrick
|
4
4
|
class Step
|
5
5
|
attr_reader :step_def, :wizard
|
6
|
+
attr_accessor :next_step, :redirect_from
|
6
7
|
attr_writer :skipped
|
7
|
-
attr_accessor :next_step
|
8
8
|
|
9
|
-
delegate :name, :fieldset, :
|
10
|
-
:run_after_callback, :run_before_callback, :
|
11
|
-
:run_include_data_callback, :
|
9
|
+
delegate :name, :fieldset, :add_button, :buttons, :to_sym, :to_s,
|
10
|
+
:run_after_callback, :run_before_callback, :include_data,
|
11
|
+
:run_include_data_callback, :run_step_contents_callback,
|
12
|
+
:include_data_key, :config, :step_contents, :last?, :first?,
|
13
|
+
:to => :step_def
|
14
|
+
|
15
|
+
delegate :visited_steps, :skipped_steps, :to => :wizard
|
12
16
|
|
13
17
|
def initialize(step_def, wizard)
|
14
18
|
@step_def = step_def
|
@@ -16,20 +20,29 @@ module HatTrick
|
|
16
20
|
@skipped = step_def.skipped?
|
17
21
|
end
|
18
22
|
|
19
|
-
def
|
20
|
-
|
23
|
+
def skipped?
|
24
|
+
@skipped || (skipped_steps.include?(self.to_sym) && !visited?)
|
21
25
|
end
|
22
26
|
|
23
|
-
def
|
24
|
-
|
27
|
+
def redirect?
|
28
|
+
redirect_from.present?
|
25
29
|
end
|
26
30
|
|
27
31
|
def visited?
|
28
|
-
|
32
|
+
visited_steps.include? self.to_sym
|
33
|
+
end
|
34
|
+
|
35
|
+
def mark_as_visited
|
36
|
+
visited_steps << self.to_sym
|
29
37
|
end
|
30
38
|
|
31
|
-
def
|
32
|
-
|
39
|
+
def as_json(options = nil)
|
40
|
+
json = { :name => name, :fieldset => fieldset }
|
41
|
+
json[:buttons] = buttons.empty? ? [] : buttons
|
42
|
+
json[:first] = first?
|
43
|
+
json[:redirect] = redirect?
|
44
|
+
json[:redirectFrom] = redirect_from
|
45
|
+
json
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|