jeffp-wizardly 0.1.8.1 → 0.1.8.3

Sign up to get free protection for your applications and to get access to all the features.
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