jeffp-wizardly 0.1.8.1 → 0.1.8.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/README.rdoc CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  == Resources
6
6
 
7
- Development
7
+ Examples
8
8
 
9
- * http://github.com/jeffp/wizardly
9
+ * http://github.com/jeffp/wizardly-examples
10
10
 
11
11
  Source
12
12
 
@@ -34,7 +34,7 @@ Features include:
34
34
 
35
35
  Put the following in your application's config block in config/environment.rb
36
36
 
37
- config.gem 'jeffp-wizardly', :lib=>'wizardly'
37
+ config.gem 'jeffp-wizardly', :lib=>'wizardly'
38
38
 
39
39
  and run the install gems rake task on your application
40
40
 
@@ -44,6 +44,20 @@ For any rails app, run the following to install wizardly rake tasks (optional)
44
44
 
45
45
  ./script/generate wizardly_app
46
46
 
47
+ == Recommendations
48
+
49
+ Wizardly uses sessions. It is recommended you use a session store other than the
50
+ default cookies store to eliminate the 4KB size restriction. To use the active
51
+ record store, add this line to your environment.rb
52
+
53
+ config.action_controller.session_store = :active_record_store
54
+
55
+ And set up the sessions table in the database
56
+
57
+ rake db:sessions:create
58
+ rake db:migrate
59
+
60
+ Use the MemCached session store for higher performance requirements.
47
61
 
48
62
  == Example
49
63
 
@@ -69,7 +83,9 @@ Step 3: Generate a 'wizardly' scaffold for your controller.
69
83
 
70
84
  You are ready to go.
71
85
 
72
- General usage and configuration of wizardly follows.
86
+ General usage and configuration of wizardly follows. See the examples at
87
+
88
+ http://github.com/jeffp/wizardly-examples
73
89
 
74
90
  == Usage
75
91
 
@@ -312,6 +328,23 @@ call back for this.
312
328
  end
313
329
  end
314
330
 
331
+ === Completing the Wizard Programmatically
332
+
333
+ Perhaps you want to complete a wizard based off of a test instead of a button
334
+ click. You can do this in your callbacks by calling the +complete_wizard+ method.
335
+
336
+ on_next(:step4) do
337
+ if (test_radio_button)
338
+ complete_wizard
339
+ end
340
+ end
341
+
342
+ Complete wizard will save the model and redirect to the :completed redirect setting.
343
+ You can change the redirect dynamically by passing it to the method.
344
+
345
+ complete_wizard(some_model_path)
346
+
347
+
315
348
  === Creating Scaffolds
316
349
 
317
350
  Wizard scaffolds can be created for any wizardly controller (one using the acts_wizardly_for
@@ -329,6 +362,11 @@ each page.
329
362
 
330
363
  ./script/generate wizardly_scaffold controller_name --underscore
331
364
 
365
+ You can create a scaffold using image_submit_tag by doing the following:
366
+
367
+ ./script/generate wizardly_scaffold controller_name --image_submit
368
+
369
+ Default button images are provided under the public/images/wizardly/ directory.
332
370
 
333
371
  == Advanced Configuration
334
372
 
@@ -336,7 +374,7 @@ To be provided
336
374
 
337
375
  == Testing
338
376
 
339
- Testing uses RSpec and Webrat. Make sure you have those gems installed. Then
377
+ Testing uses RSpec and Webrat. Make sure you have the gems installed. Then
340
378
  to test the development code run the following:
341
379
 
342
380
  rake spec:all
@@ -44,7 +44,7 @@ module ValidationGroup
44
44
 
45
45
  module InstanceMethods # included in every model which calls validation_group
46
46
  #needs testing
47
- # def reset_validation_group(group)
47
+ # def reset_fields_for_validation_group(group)
48
48
  # group_classes = self.class.validation_group_classes
49
49
  # found = ValidationGroup::Util.current_and_ancestors(self.class).find do |klass|
50
50
  # group_classes[klass] && group_classes[klass].include?(group)
@@ -7,12 +7,15 @@ require 'wizardly/wizard/configuration/methods'
7
7
  module Wizardly
8
8
  module Wizard
9
9
  class Configuration
10
- attr_reader :pages, :completed_redirect, :canceled_redirect, :controller_name, :page_order
10
+ attr_reader :pages, :completed_redirect, :canceled_redirect, :controller_path, :controller_class_name, :controller_name, :page_order
11
11
 
12
12
  #enum_attr :persistance, %w(sandbox session database)
13
13
 
14
- def initialize(controller_name, opts) #completed_redirect = nil, canceled_redirect = nil)
15
- @controller_name = controller_name
14
+ def initialize(controller, opts) #completed_redirect = nil, canceled_redirect = nil)
15
+ @controller_class_name = controller.to_s.camelcase
16
+ @controller_class_name += 'Controller' unless @controller_class_name =~ /Controller$/
17
+ @controller_path = @controller_class_name.sub(/Controller$/,'').underscore
18
+ @controller_name = @controller_class_name.demodulize.sub(/Controller$/,'').underscore
16
19
  @completed_redirect = opts[:redirect] || opts[:completed] || opts[:when_completed] #format_redirect(completed_redirect)
17
20
  @canceled_redirect = opts[:redirect] || opts[:canceled] || opts[:when_canceled]
18
21
  @allow_skipping = opts[:skip] || opts[:allow_skip] || opts[:allow_skipping] || false
@@ -59,7 +62,7 @@ module Wizardly
59
62
  end
60
63
 
61
64
  def self.create(controller_name, model_name, opts={}, &block)
62
- controller_name = controller_name.to_s.underscore.sub(/_controller$/, '').to_sym
65
+ # controller_name = controller_name.to_s.underscore.sub(/_controller$/, '').to_sym
63
66
  model_name = model_name.to_s.underscore.to_sym
64
67
  config = Wizardly::Wizard::Configuration.new(controller_name, opts)
65
68
  config.inspect_model!(model_name)
@@ -53,16 +53,22 @@ MACRO
53
53
  INDEX
54
54
  mb.string
55
55
  end
56
-
57
- def persist_key;
58
- @persist_key ||= "wizardly_#{controller_name.to_s.underscore}_#{model}".to_sym
59
- end
60
-
56
+
57
+ def initial_referer_key
58
+ @initial_referer_key ||= "#{self.controller_path.sub(/\//, '')}_irk".to_sym
59
+ end
60
+ def persist_key;
61
+ @persist_key ||= "#{self.controller_path.sub(/\//, '')}_dat".to_sym
62
+ end
63
+ def progression_key
64
+ @progression_key ||= "#{self.controller_path.sub(/\//, '')}_prg".to_sym
65
+ end
66
+
61
67
  def print_page_action_method(id)
62
68
  page = @pages[id]
63
69
  finish_button = self.button_for_function(:finish).id
64
70
  next_button = self.button_for_function(:next).id
65
- model_persist_line = self.persist_model_per_page? ? 'save_wizard_model!' : ''
71
+ model_persist_line = self.persist_model_per_page? ? "@#{self.model}.save_without_validation!" : ''
66
72
 
67
73
  (mb = StringIO.new) << <<-ONE
68
74
  def #{page.name}
@@ -95,15 +101,13 @@ MACRO
95
101
  if self.last_page?(id)
96
102
  mb << <<-TWO
97
103
  callback_performs_action?(:on_#{id}_form_#{finish_button})
98
- _on_wizard_#{finish_button}
99
- redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
104
+ complete_wizard
100
105
  TWO
101
106
  elsif self.first_page?(id)
102
107
  mb << <<-THREE
103
108
  if button_id == :#{finish_button}
104
109
  callback_performs_action?(:on_#{id}_form_#{finish_button})
105
- _on_wizard_#{finish_button} if button_id == :#{finish_button}
106
- redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
110
+ complete_wizard
107
111
  return
108
112
  end
109
113
  #{model_persist_line}
@@ -114,8 +118,7 @@ MACRO
114
118
  mb << <<-FOUR
115
119
  if button_id == :#{finish_button}
116
120
  callback_performs_action?(:on_#{id}_form_#{finish_button})
117
- _on_wizard_#{finish_button} if button_id == :#{finish_button}
118
- redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
121
+ complete_wizard
119
122
  return
120
123
  end
121
124
  #{model_persist_line}
@@ -147,7 +150,7 @@ ENSURE
147
150
  _wizard_final_redirect_to(:completed)
148
151
  end
149
152
  def _on_wizard_#{skip}
150
- session[:progression] = (session[:progression]||[]) - [@step]
153
+ self.progression = self.progression - [@step]
151
154
  redirect_to(:action=>wizard_config.next_page(@step)) unless self.performed?
152
155
  end
153
156
  def _on_wizard_#{back}
@@ -156,12 +159,12 @@ ENSURE
156
159
  def _on_wizard_#{cancel}
157
160
  _wizard_final_redirect_to(:canceled)
158
161
  end
159
- def _wizard_final_redirect_to(type)
160
- initial_referer = (type == :canceled && wizard_config.form_data_keep_in_session?) ?
161
- session[:initial_referer] :
162
+ def _wizard_final_redirect_to(type)
163
+ init = (type == :canceled && wizard_config.form_data_keep_in_session?) ?
164
+ self.initial_referer :
162
165
  reset_wizard_session_vars
163
166
  unless self.performed?
164
- redir = (type == :canceled ? wizard_config.canceled_redirect : wizard_config.completed_redirect) || initial_referer
167
+ redir = (type == :canceled ? wizard_config.canceled_redirect : wizard_config.completed_redirect) || init
165
168
  return redirect_to(redir) if redir
166
169
  raise Wizardly::RedirectNotDefinedError, "No redirect was defined for completion or canceling the wizard. Use :completed and :canceled options to define redirects.", caller
167
170
  end
@@ -174,26 +177,27 @@ ENSURE
174
177
  next_id = self.button_for_function(:next).id
175
178
  finish_id = self.button_for_function(:finish).id
176
179
  first_page = self.page_order.first
180
+ finish_button = self.button_for_function(:finish).id
177
181
  guard_line = self.guard? ? '' : 'return check_progression #guard entry disabled'
178
182
  mb = StringIO.new
179
183
  mb << <<-PROGRESSION
180
184
  protected
181
185
  def previous_in_progression_from(step)
182
- po = wizard_config.page_order
183
- p = session[:progression]||[]
186
+ po = #{self.page_order.inspect}
187
+ p = self.progression
184
188
  p -= po[po.index(step)..-1]
185
- session[:progression] = p
189
+ self.progression = p
186
190
  p.last
187
191
  end
188
192
  def check_progression
189
- p = session[:progression]||[]
193
+ p = self.progression
190
194
  a = params[:action].to_sym
191
195
  return if p.last == a
192
- po = wizard_config.page_order
196
+ po = #{self.page_order.inspect}
193
197
  return unless (ai = po.index(a))
194
198
  p -= po[ai..-1]
195
199
  p << a
196
- session[:progression] = p
200
+ self.progression = p
197
201
  end
198
202
  PROGRESSION
199
203
  if self.form_data_keep_in_session?
@@ -203,14 +207,14 @@ PROGRESSION
203
207
  if (r = request.env['HTTP_REFERER'])
204
208
  h = ::ActionController::Routing::Routes.recognize_path(URI.parse(r).path)
205
209
  return check_progression if (h[:controller]||'') == '#{self.controller_name}'
206
- session[:initial_referer] ||= h
210
+ self.initial_referer = h unless self.initial_referer
207
211
  end
208
212
  # coming from outside the controller
209
213
  #{guard_line}
210
214
  if (params[:action] == '#{first_page}' || params[:action] == 'index')
211
215
  return check_progression
212
216
  elsif self.wizard_form_data
213
- p = session[:progression]||[]
217
+ p = self.progression
214
218
  return check_progression if p.include?(params[:action].to_sym)
215
219
  return redirect_to(:action=>(p.last||:#{first_page}))
216
220
  end
@@ -226,9 +230,9 @@ SESSION
226
230
  if (r = request.env['HTTP_REFERER'])
227
231
  h = ::ActionController::Routing::Routes.recognize_path(URI.parse(r).path)
228
232
  return check_progression if (h[:controller]||'') == '#{self.controller_name}'
229
- session[:initial_referer] = h
233
+ self.initial_referer = h
230
234
  else
231
- session[:initial_referer] = nil
235
+ self.initial_referer = nil
232
236
  end
233
237
  # coming from outside the controller
234
238
  reset_wizard_form_data
@@ -241,25 +245,38 @@ SESSION
241
245
  SANDBOX
242
246
  end
243
247
  mb << <<-HELPERS
244
- def save_wizard_model!
245
- @#{self.model}.save_without_validation!
246
- if wizard_config.form_data_keep_in_session?
247
- h = self.wizard_form_data
248
- h['id'] = @#{self.model}.id
249
- self.wizard_form_data= h
250
- end
248
+ def complete_wizard(redirect = nil)
249
+ redirect_to redirect if redirect
250
+ _on_wizard_#{finish_button}
251
+ redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
251
252
  end
252
253
  def build_wizard_model(params)
253
254
  if (wizard_config.persist_model_per_page? && (model_id = params['id']))
254
- _model = #{self.model_class_name}.find(model_id)
255
- _model.attributes = params
256
- _model
257
- else
258
- #{self.model_class_name}.new(params)
255
+ begin
256
+ _model = #{self.model_class_name}.find(model_id)
257
+ _model.attributes = params
258
+ return _model
259
+ rescue
260
+ end
259
261
  end
262
+ #{self.model_class_name}.new(params)
260
263
  end
261
264
  hide_action :build_wizard_model, :save_wizard_model!
262
265
 
266
+ def initial_referer
267
+ session[:#{self.initial_referer_key}]
268
+ end
269
+ def initial_referer=(val)
270
+ session[:#{self.initial_referer_key}] = val
271
+ end
272
+ def progression=(array)
273
+ session[:#{self.progression_key}] = array
274
+ end
275
+ def progression
276
+ session[:#{self.progression_key}]||[]
277
+ end
278
+ hide_action :progression, :progression=
279
+
263
280
  def wizard_form_data=(hash)
264
281
  if wizard_config.form_data_keep_in_session?
265
282
  session[:#{self.persist_key}] = hash
@@ -291,9 +308,9 @@ SANDBOX
291
308
  hide_action :underscore_button_name
292
309
 
293
310
  def reset_wizard_session_vars
294
- session[:progression] = nil
295
- init = session[:initial_referer]
296
- session[:initial_referer] = nil
311
+ self.progression = nil
312
+ init = self.initial_referer
313
+ self.initial_referer = nil
297
314
  init
298
315
  end
299
316
  hide_action :reset_wizard_session_vars
@@ -319,9 +336,19 @@ SANDBOX
319
336
  end
320
337
  hide_action :check_action_for_button
321
338
 
322
- def callback_performs_action?(methId, arg=nil)
323
- return false unless self.methods.include?(methId.to_s)
324
- #self.__send__(methId)
339
+ @wizard_callbacks ||= {}
340
+ def self.wizard_callbacks; @wizard_callbacks; end
341
+
342
+ def callback_performs_action?(methId)
343
+ cache = self.class.wizard_callbacks
344
+ return false if ((m = cache[methId]) == :none)
345
+ unless m == :found
346
+ unless self.methods.include?(methId.to_s)
347
+ cache[methId] = :none
348
+ return false
349
+ end
350
+ cache[methId] = :found
351
+ end
325
352
  self.method(methId).call
326
353
  self.performed?
327
354
  end
@@ -5,7 +5,7 @@ class WizardlyControllerGenerator < Rails::Generator::Base
5
5
 
6
6
  def initialize(runtime_args, runtime_options = {})
7
7
  super
8
- @controller_name = @args[0].sub(/^:/, '').underscore
8
+ @controller_name = @args[0].sub(/^:/,'')
9
9
  @model_name = @args[1].sub(/^:/, '').underscore
10
10
  @completed_redirect = @args[2]
11
11
  @canceled_redirect = @args[3]
@@ -13,7 +13,7 @@ class WizardlyControllerGenerator < Rails::Generator::Base
13
13
  opts[:completed] = @completed_redirect if @completed_redirect
14
14
  opts[:canceled] = @canceled_redirect if @canceled_redirect
15
15
 
16
- @wizard_config = Wizardly::Wizard::Configuration.new(@controller_name.to_sym, opts)
16
+ @wizard_config = Wizardly::Wizard::Configuration.new(@controller_name, opts)
17
17
  @wizard_config.inspect_model!(@model_name.to_sym)
18
18
  end
19
19
 
@@ -14,7 +14,7 @@
14
14
  </p>
15
15
  <% end -%>
16
16
  <p>
17
- <%%= wizardly_submit %>
17
+ <%%= <%= submit_tag %> %>
18
18
  </p>
19
19
  <%% end %>
20
20
 
@@ -16,7 +16,7 @@
16
16
  %br
17
17
  = f.<%= field.field_type %> :<%= field.name %>
18
18
  <% end %>
19
- %p= wizardly_submit
19
+ %p= <%= submit_tag %>
20
20
 
21
21
  %script{:type=>'text/javascript'}
22
22
  document.getElementById('<%=first_field_id %>').focus()
@@ -2,13 +2,29 @@ module <%=controller_name.camelize %>Helper
2
2
 
3
3
  def wizardly_submit
4
4
  @@wizardly_submit ||= {}
5
- unless @@wizardly_submit[@step]
5
+ step_id = "#{controller_name}_#{@step}".to_sym
6
+ unless @@wizardly_submit[step_id]
6
7
  buttons = @wizard.pages[@step].buttons
7
- @@wizardly_submit[@step] = buttons.inject(StringIO.new) do |io, button|
8
+ @@wizardly_submit[step_id] = buttons.inject(StringIO.new) do |io, button|
8
9
  io << submit_tag(button.name)
9
10
  end.string
10
11
  end
11
- @@wizardly_submit[@step]
12
+ @@wizardly_submit[step_id]
13
+ end
14
+
15
+ def wizardly_image_submit(asset_dir = nil, opts = {})
16
+ @@wizardly_image_submit ||={}
17
+ step_id = "#{controller_name}_#{@step}".to_sym
18
+ unless @@wizardly_image_submit[step_id]
19
+ asset_dir = asset_dir ? "#{asset_dir}/".squeeze("/").sub(/^\//,'') : "wizardly/"
20
+ buttons = @wizard.pages[@step].buttons
21
+ opts[:name] = 'commit'
22
+ @@wizardly_image_submit[step_id] = buttons.inject(StringIO.new) do |io, button|
23
+ opts[:value] = button.name
24
+ io << image_submit_tag("#{asset_dir}#{button.id}.png", opts)
25
+ end.string
26
+ end
27
+ @@wizardly_image_submit[step_id]
12
28
  end
13
29
 
14
30
  end
@@ -1,7 +1,7 @@
1
1
  require 'wizardly'
2
2
 
3
3
  class WizardlyScaffoldGenerator < Rails::Generator::Base
4
- attr_reader :wizard_config, :pages
4
+ attr_reader :wizard_config, :pages, :submit_tag
5
5
  attr_reader :controller_name,
6
6
  :controller_class_path,
7
7
  :controller_file_path,
@@ -17,6 +17,7 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
17
17
  opt.on('--haml', 'Generate scaffold for haml wizard') { |v| options[:output] = :haml }
18
18
  opt.on('--ajax', 'Generate scaffold for ajax wizard') { |v| options[:output] = :ajax }
19
19
  opt.on('--underscore', 'Append an underscore to front of each file') { |v| options[:underscore] = true }
20
+ opt.on('--image_submit', 'Use image submit tags in forms') {|v| options[:image_submit] = true }
20
21
  end
21
22
 
22
23
 
@@ -47,6 +48,7 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
47
48
 
48
49
  @pages = @wizard_config.pages
49
50
  @model_name = @wizard_config.model
51
+ @submit_tag = options[:image_submit] ? "wizardly_image_submit" : "wizardly_submit"
50
52
 
51
53
  #based on options, default is --html, others --ajax, --haml
52
54
  @view_file_ext = ["html.erb", "html.erb"]
@@ -60,6 +62,7 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
60
62
  m.directory(File.join('app/helpers', controller_class_path))
61
63
  m.directory(File.join('app/views', controller_class_path, controller_name))
62
64
  m.directory(File.join('app/views/layouts', controller_class_path))
65
+ m.directory('public/images/wizardly') if options[:image_submit]
63
66
  #m.directory(File.join('test/functional', controller_class_path))
64
67
  #m.directory(File.join('public/stylesheets', class_path))
65
68
 
@@ -72,6 +75,12 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
72
75
  )
73
76
  end
74
77
 
78
+ if options[:image_submit]
79
+ %w(next skip back cancel finish).each do |fn|
80
+ m.file("images/#{fn}.png", "public/images/wizardly/#{fn}.png")
81
+ end
82
+ end
83
+
75
84
  m.template("helper.rb.erb", File.join('app/helpers', controller_class_path, "#{controller_name}_helper.rb"))
76
85
 
77
86
  # Layout and stylesheet.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeffp-wizardly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8.1
4
+ version: 0.1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Patmon
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-14 00:00:00 -07:00
12
+ date: 2009-08-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -54,6 +54,12 @@ files:
54
54
  - rails_generators/wizardly_scaffold/templates/form.html.erb
55
55
  - rails_generators/wizardly_scaffold/templates/form.html.haml.erb
56
56
  - rails_generators/wizardly_scaffold/templates/helper.rb.erb
57
+ - rails_generators/wizardly_scaffold/templates/images
58
+ - rails_generators/wizardly_scaffold/templates/images/back.png
59
+ - rails_generators/wizardly_scaffold/templates/images/cancel.png
60
+ - rails_generators/wizardly_scaffold/templates/images/finish.png
61
+ - rails_generators/wizardly_scaffold/templates/images/next.png
62
+ - rails_generators/wizardly_scaffold/templates/images/skip.png
57
63
  - rails_generators/wizardly_scaffold/templates/layout.html.erb
58
64
  - rails_generators/wizardly_scaffold/templates/layout.html.haml.erb
59
65
  - rails_generators/wizardly_scaffold/templates/style.css