ns-ramaze-ext 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,5 @@
1
+ v0.0.3 : minimal documentation for github
2
+
3
+ v0.0.2 : implementation of the style parameters and error handling summary
4
+
5
+ v0.0.1 : first version, derived from ramaze blue_form.rb
data/Manifest ADDED
@@ -0,0 +1,11 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README
4
+ Rakefile
5
+ lib/ext/ramaze/helper/banana_form.rb
6
+ lib/ns-ramaze-ext.rb
7
+ rake/doc.rb
8
+ rake/gemdef.rb
9
+ rake/rake.rb
10
+ rake/tests.rb
11
+ tests/ramaze/helper/banana_form.rb
data/README ADDED
@@ -0,0 +1,48 @@
1
+ = ns-ramaze-ext gem
2
+
3
+ The purpose of this gem is to provide some extensions to the ramaze web framework.
4
+
5
+ == Features
6
+
7
+ === Form Helpers
8
+
9
+ BananaFrom is a form helper that provides a Rails like behaviour for validation
10
+ errors in forms and extra parameters for field/label styling.
11
+
12
+ Check the doc for Ramaze::Helper::BananaForm.
13
+
14
+ == Installation
15
+
16
+ === Requirements
17
+
18
+ Mandatory :
19
+
20
+ * gem install echoe
21
+ * gem install rake
22
+ * gem install ramaze
23
+
24
+ Recommended :
25
+
26
+ * gem install bacon
27
+
28
+
29
+ === Procedure
30
+
31
+ * Get the files from the github and perform the following operations :
32
+
33
+ * Execute commands :
34
+
35
+ * rake gems:ns-ramaze-ext:build
36
+ * rake reinstall
37
+
38
+ == Doc generation
39
+
40
+ Run the following command
41
+
42
+ * rake doc
43
+
44
+ == Testing
45
+
46
+ Run the following command
47
+
48
+ * rake tests
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+ #require 'ns-gems-devtools'
5
+ require 'spec/rake/spectask'
6
+ require 'rake/rake.rb'
7
+
8
+ namespace 'gems' do
9
+ namespace GEM_NAME do
10
+ #include NS::Build::GemSpecConstants
11
+ Echoe.new(GEM_NAME) do |p|
12
+ p.description = GEM_DESC
13
+ p.url = GEM_URL
14
+ p.author = GEM_AUTHOR
15
+ p.email = GEM_EMAIL
16
+ p.ignore_pattern = GEM_IGNORE
17
+ p.development_dependencies = GEM_DEPENDS_ON
18
+ p.runtime_dependencies = GEM_DEPENDS_ON
19
+ end
20
+ end
21
+ end
22
+
23
+ CLEAN.add(FileList["pkg/**/*"])
24
+
25
+
26
+ desc 'dev shortucut for reinstall'
27
+ task :reinstall => [ "gems:#{GEM_NAME}:install"]
28
+
29
+ desc "dev shortcut for running all the tests"
30
+ task :tests => [ "gems:#{GEM_NAME}:tests:banana-form" ]
31
+
32
+ desc "dev shortcut for creating gem doc"
33
+ task :doc => [ "gems:#{GEM_NAME}:doc" ]
34
+
35
+
36
+ desc 'clean all'
37
+ task :clean
38
+
39
+
40
+
@@ -0,0 +1,566 @@
1
+ require 'ramaze'
2
+ require 'ramaze/gestalt'
3
+
4
+ module Ramaze
5
+ module Helper
6
+
7
+ ## = Banana Form Helper
8
+ ##
9
+ ## == Overview
10
+ ##
11
+ ## The banana form heloer is derived from the ramaze standard BlueForm helper.
12
+ ##
13
+ ## == Features:
14
+ ##
15
+ ## * provide additional parameters for form element css class styling
16
+ ##
17
+ ## * provide form error management that includes an error summary and css
18
+ ## style changing on impacted fields, very much like the rails view helper
19
+ ##
20
+ ## == Styling
21
+ ##
22
+ ## All the BananaForm::Form methods accept the following parameters for css styling :
23
+ ##
24
+ ## * *class* : class for the input element
25
+ ## * *class_label* : class for the input label
26
+ ## * *class_error* : class for input in case of validation errors on that field
27
+ ## * *class_label_error* : class for the label if any validation errors occur on the related input field
28
+ ##
29
+ ## == Error Handling
30
+ ##
31
+ ## The errors are declared in the very same way that in the BlueFrom, however the form
32
+ ## behavior is different.
33
+ ##
34
+ ## If errors have been declared, prior to form construction, the form helper class
35
+ ## will check the existing errors and corelate them with input fields.
36
+ ##
37
+ ## The labels and fields linked to the errors will have their class attribute changed
38
+ ## in order to apply some highlighting or any other presentation layer that would provide
39
+ ## the user with hints.
40
+ ##
41
+ ## Further, the form will have a div section that will display an error summary very similar
42
+ ## to the one provided by rails view helper.
43
+ ##
44
+ ## All styles, including the summary related can be overridden by providing the appropriate
45
+ ## parameters in the Ramaze::Helper::BananaForm::Form methods.
46
+ ##
47
+ ## Please note that the gem and helper don't provide any of the css styles and that we consider
48
+ ## that this is part of your job.
49
+ ##
50
+ ## === Declaring Errors
51
+ ##
52
+ ## The errors are declared *before* the form is constructed using the following module methods :
53
+ ##
54
+ ## * Ramaze::Helper::BananaForm.form_error : adds a new error with name and message
55
+ ##
56
+ ## * Ramaze::Helper::BananaForm.form_errors_from_model : adds all the errors contained in a 'model' class instance (i.e providing errors hash)
57
+ ##
58
+ ##
59
+ ## Please note that those are the same methods than in *BlueForm*, and that the source code is unchanged.
60
+ ##
61
+ ## === Error Summary Default Properties
62
+ ##
63
+ ## The summary will be inserted as a div element *before* the fieldset tag.
64
+ ##
65
+ ## Default *id* and *class* are set to the *form_error_summary* value. If you want to see something
66
+ ## fancy in a minimum laps of type just copy the rails *errorExplanation* style to *form_error_summary* and
67
+ ## include it in your form page.
68
+ ##
69
+ ## === Default Field and Labels styles
70
+ ##
71
+ ## The form construction is managed by the Ramaze::Helper::BananaForm::Form class, so please check the documentation
72
+ ## of the class methods in order to find out the default styles.
73
+ ##
74
+ ## == Examples
75
+ ##
76
+ ## There are a bunch of examples in the specs located under the test directory of the gem.
77
+ ## It is probably your best way into BananaForm ...
78
+ ##
79
+
80
+ module BananaForm
81
+
82
+ ## == Constructs a new form
83
+ ##
84
+ ## Constructs a form with options and an optional block that will provide content
85
+ ##
86
+ ## === Example :
87
+ ##
88
+ ## form(:method => :post, :action => :create, :name => 'user' ) do |f|
89
+ ## f.legend('User Details')
90
+ ## f.input_text 'Username', :username, @user.username
91
+ ## f.input_submit 'Create New User'
92
+ ## end
93
+ ##
94
+ ## === Note :
95
+ ##
96
+ ## In a templating engine, you need to do this with an assignement statement.
97
+ ## For instance with Erubis it would look like this :
98
+ ##
99
+ ## <%=
100
+ ## form(:method => :post, :action => :create, :name => 'user' ) do |f|
101
+ ## ...
102
+ ## end
103
+ ## %>
104
+ ##
105
+ def form(options = {}, &block)
106
+ form = Form.new(options)
107
+ form.build(form_errors, &block)
108
+ form
109
+ end
110
+
111
+ ## == Adds an error to be managed by the form helper
112
+ ##
113
+ ## Uses flash[:form_errors] placeholder is flash is available,
114
+ ## creates an empty hash if not.
115
+ ##
116
+ ## Errors are stored as key/values of the hash.
117
+ ##
118
+ def form_error(name, message)
119
+ if respond_to?(:flash)
120
+ old = flash[:form_errors] || {}
121
+ flash[:form_errors] = old.merge(name.to_s => message.to_s)
122
+ else
123
+ form_errors[name.to_s] = message.to_s
124
+ end
125
+ end
126
+
127
+ ## == Returns the error hash
128
+ ##
129
+ ## Code inherited from Ramaze::Helper::BlueForm seems to return the used error hash.
130
+ ##
131
+ def form_errors
132
+ if respond_to?(:flash)
133
+ flash[:form_errors] ||= {}
134
+ else
135
+ @form_errors ||= {}
136
+ end
137
+ end
138
+
139
+ ## == Adds errors contained in a model instance
140
+ ##
141
+ ## The method assumes that the object reference you're passing as argument
142
+ ## responds to a method named *errors* that return a Hash of errors
143
+ ##
144
+ ## It iterates over errors and call the form_error method to insert each error
145
+ ##
146
+ def form_errors_from_model(obj)
147
+ obj.errors.each do |key, value|
148
+ form_error(key.to_s, value.first % key)
149
+ end
150
+ end
151
+
152
+ ## == Banana form helper manager class
153
+ ##
154
+ ## Provide methods to build a form and use the banana error handling features.
155
+ ##
156
+ ## == Notes
157
+ ##
158
+ ## This code is based on the Ramaze::Helper::BlueForm::Form class and *is not thread safe* , so make sure
159
+ ## you're not using it from several execution threads.
160
+ ##
161
+ class Form
162
+
163
+ ## Gestalt HTML Builder
164
+ attr_reader :g
165
+ ## Structure containing the summary parameters before final construction
166
+ attr_reader :error_summary_args
167
+
168
+ ## == Initializes an instance of the class
169
+ ##
170
+ ## Accepts following extra parameters for error summary :
171
+ ##
172
+ ## * *error_summary_title* : sets the main summary title, defaults to "X error(s) prohibited this form from being saved" where X is the number of errors
173
+ ##
174
+ ## * *error_summary_subtitle* : sets the subtitle of the summary title, default to 'Following fields reported errors:'
175
+ ##
176
+ ## * *error_summary_class* : sets the summary div class, defaults to 'form_error_summary'
177
+ ##
178
+ ## * *error_summary_id* : sets the summary div id, defaults to 'form_error_summary'
179
+ ##
180
+ ##
181
+ def initialize(options)
182
+ @form_args = options.dup
183
+ @error_encart_args = {}
184
+ @error_encart_args[:title] = @form_args.delete(:error_summary_title)
185
+ @error_encart_args[:subtitle] = @form_args[:error_summary_subtitle] ? @form_args.delete(:error_summary_subtitle) : 'Following fields reported errors:'
186
+ @error_encart_args[:class] = @form_args[:error_summary_class] ? @form_args.delete(:error_summary_class) : 'form_error_summary'
187
+ @error_encart_args[:id] = @form_args[:error_summary_id] ? @form_args.delete(:error_summary_id) : 'form_error_summary'
188
+ @g = Gestalt.new
189
+ @error_encart = nil
190
+ end
191
+
192
+ ## == Builds the form
193
+ ##
194
+ ## Builds the form (and summary), sets up the errors from module error holder
195
+ ##
196
+ ## Called by form method, should not be invoked from outside.
197
+ ##
198
+ def build(form_errors = {})
199
+ @form_errors = form_errors
200
+ @g.form(@form_args) do
201
+ ## form validation summary
202
+ if ( @form_errors!=nil && @error_encart_args && @form_errors.size>0)
203
+ @error_encart_args[:title] = "#{@form_errors.size} error(s) prohibited this form from being saved" unless @error_encart_args[:title]
204
+ @g.div(:id=>@error_encart_args[:id],:class=>@error_encart_args[:class]) {
205
+ @g.h2("#{@error_encart_args[:title]}")
206
+ @g.p("#{@error_encart_args[:subtitle]}")
207
+ @g.ul() {
208
+ @form_errors.each_pair { |name, val| @g.li("#{name} : #{val}") }
209
+ }
210
+ }
211
+ end
212
+ ## now yeld block instructions
213
+ if block_given?
214
+ @g.fieldset do
215
+ yield self
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ ## == Places a legend over the form fieldset
222
+ ##
223
+ ## Params:
224
+ ##
225
+ ## *text* : legend to display
226
+ ##
227
+ def legend(text)
228
+ @g.legend(text)
229
+ end
230
+
231
+ ## == Creates a text input field
232
+ ##
233
+ ## Creates a label and an input field of type 'text'.
234
+ ##
235
+ ## ==== Default styles :
236
+ ##
237
+ ## * input field is set to *text_input* class unless *class* is provided in the args hash
238
+ ##
239
+ ## * label field is set to *text_label* class unless *class_label* is provided in the args hash
240
+ ##
241
+ ## ==== Error styles :
242
+ ##
243
+ ## If an error occurs then both class names will be appended with a _error ( text_input will become text_input_error ... ).
244
+ ##
245
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
246
+ ##
247
+
248
+ def input_text(label, name, value = nil, args = {})
249
+ id = id_for(name)
250
+ args = args.merge(:type => :text, :name => name, :id => id)
251
+ args[:value] = value unless value.nil?
252
+ ## set up style classes, delete errors and clean additional params
253
+ css_classes = get_css_classes_clean(name,args)
254
+ args[:class] = css_classes[:input_class]
255
+ @g.p do
256
+ label_for(id, label, name, :class=>css_classes[:label_class])
257
+ @g.input(args)
258
+ end
259
+ end
260
+ alias text input_text
261
+
262
+ ## == Creates a password input field
263
+ ##
264
+ ## Creates a label and an input field of type 'password'.
265
+ ##
266
+ ## ==== Default styles :
267
+ ##
268
+ ## * input field is set to *text_input* class unless *class* is provided in the args hash
269
+ ##
270
+ ## * label field is set to *text_label* class unless *class_label* is provided in the args hash
271
+ ##
272
+ ## ==== Error styles :
273
+ ##
274
+ ## If an error occurs then both class names will be appended with a _error ( text_input will become text_input_error ... ).
275
+ ##
276
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
277
+ ##
278
+
279
+ def input_password(label, name, args={})
280
+ id = id_for(name)
281
+ args = args.merge(:type => :password, :name => name, :id => id)
282
+ ## set up style classes, delete errors and clean additional params
283
+ css_classes = get_css_classes_clean(name,args)
284
+ args[:class] = css_classes[:input_class]
285
+
286
+ @g.p do
287
+ label_for(id, label, name,:class=>css_classes[:label_class])
288
+ @g.input(args)
289
+ end
290
+ end
291
+ alias password input_password
292
+
293
+ ## == Creates a submit button
294
+ ##
295
+ ## Creates a submit button
296
+ ##
297
+ ## ==== Default styles :
298
+ ##
299
+ ## * buton is set to *button_submit* class unless *class* is provided in the args hash
300
+ ##
301
+ def input_submit(value = nil, args={})
302
+ args = args.merge(:type => :submit)
303
+ args[:class] = 'button_submit' unless args[:class]
304
+ args[:value] = value unless value.nil?
305
+ @g.p do
306
+ @g.input(args)
307
+ end
308
+ end
309
+ alias submit input_submit
310
+
311
+
312
+ ## == Creates a checkbox input field
313
+ ##
314
+ ## Creates a label and an input field of type 'checkbox'.
315
+ ##
316
+ ## ==== Default styles :
317
+ ##
318
+ ## * input field is set to *checkbox_input* class unless *class* is provided in the args hash
319
+ ##
320
+ ## * label field is set to *checkbox_label* class unless *class_label* is provided in the args hash
321
+ ##
322
+ ## ==== Error styles :
323
+ ##
324
+ ## If an error occurs then both class names will be appended with a _error ( checkbox_input will become checkbox_input_error ... ).
325
+ ##
326
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
327
+ ##
328
+ def input_checkbox(label, name, checked = false, args={})
329
+ id = id_for(name)
330
+ args= args.merge(:type => :checkbox, :name => name, :id => id)
331
+ args[:checked] = 'checked' if checked
332
+
333
+ ## set up style classes, delete errors and clean additional params
334
+ css_classes = get_css_classes_clean(name,args,'checkbox_input','checkbox_label')
335
+ args[:class] = css_classes[:input_class]
336
+
337
+ @g.p do
338
+ label_for(id, label, name, :class=>css_classes[:label_class])
339
+ @g.input(args)
340
+ end
341
+ end
342
+ alias checkbox input_checkbox
343
+
344
+ ## == Creates a group of radio buttons
345
+ ##
346
+ ## Creates a label and an input field of type 'checkbox'.
347
+ ##
348
+ ## ==== Default styles :
349
+ ##
350
+ ## * input field is set to *radio_input* class unless *class* is provided in the args hash
351
+ ##
352
+ ## * label field is set to *radio_label* class unless *class_label* is provided in the args hash
353
+ ##
354
+ ## ==== Error styles :
355
+ ##
356
+ ## At the difference of other methods, only the class of the *checked* input field will change in case of errors.
357
+ ##
358
+
359
+ def input_radio(label, name, values, options = {})
360
+ has_checked, checked = options.key?(:checked), options[:checked]
361
+
362
+ ## not using the usual css error formatter for radio
363
+ input_class = options[:class] ? options[:class] : 'radio_input'
364
+ label_class = options[:class_label] ? options[:class_label] : 'radio_label'
365
+ error = @form_errors.delete(name.to_s)
366
+
367
+ @g.p do
368
+ values.each_with_index do |(value, o_name), index|
369
+ o_name ||= value
370
+ id = id_for("#{name}-#{index}")
371
+
372
+ o_args = {:type => :radio, :value => value, :id => id, :name => name}
373
+ o_args[:checked] = 'checked' if has_checked && value == checked
374
+
375
+ clazz_elem = (error && has_checked && value == checked ) ? "#{input_class}_error" : input_class
376
+ all_args = o_args.clone
377
+ all_args[:class] = clazz_elem
378
+
379
+ @g.label(:for=>id,:class=>label_class) {
380
+ @g.input(all_args)
381
+ @g.out << o_name
382
+ }
383
+ end
384
+ end
385
+ end
386
+ alias radio input_radio
387
+
388
+ ## == Creates a file input field
389
+ ##
390
+ ## Creates a label and an input field of type 'checkbox'.
391
+ ##
392
+ ## ==== Default styles :
393
+ ##
394
+ ## * input field is set to *file_input* class unless *class* is provided in the args hash
395
+ ##
396
+ ## * label field is set to *file_label* class unless *class_label* is provided in the args hash
397
+ ##
398
+ ## ==== Error styles :
399
+ ##
400
+ ## If an error occurs then both class names will be appended with a _error
401
+ ##
402
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
403
+ ##
404
+
405
+ def input_file(label, name, args={})
406
+ id = id_for(name)
407
+ args = args.merge(:type => :file, :name => name, :id => id)
408
+
409
+ ## set up style classes, delete errors and clean additional params
410
+ css_classes = get_css_classes_clean(name,args,'file_input','file_label')
411
+ args[:class] = css_classes[:input_class]
412
+
413
+ @g.p do
414
+ label_for(id, label, name,:class=>css_classes[:label_class])
415
+ @g.input(args)
416
+ end
417
+ end
418
+ alias file input_file
419
+
420
+ ## == Creates a hidden input field
421
+ ##
422
+ ## Creates a label and an input field of type 'hidden', no styling applies
423
+ ##
424
+ def input_hidden(name, value = nil)
425
+ args = {:type => :hidden, :name => name}
426
+ args[:value] = value.to_s unless value.nil?
427
+
428
+ @g.input(args)
429
+ end
430
+ alias hidden input_hidden
431
+
432
+ ## == Creates a text area input field
433
+ ##
434
+ ## Creates a label and an input field of type text area.
435
+ ##
436
+ ## ==== Default styles :
437
+ ##
438
+ ## * input field is set to *area_input* class unless *class* is provided in the args hash
439
+ ##
440
+ ## * label field is set to *area_label* class unless *class_label* is provided in the args hash
441
+ ##
442
+ ## ==== Error styles :
443
+ ##
444
+ ## If an error occurs then both class names will be appended with a *_error*
445
+ ##
446
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
447
+ ##
448
+ def textarea(label, name, value = nil, options={})
449
+ id = id_for(name)
450
+ args = {:name => name, :id => id }
451
+
452
+ css_classes = get_css_classes_clean(name,options,'area_input','area_label')
453
+ args[:class] = css_classes[:input_class]
454
+
455
+ @g.p do
456
+ label_for(id, label, name,:class=>css_classes[:label_class])
457
+ @g.textarea(args){ value }
458
+ end
459
+ end
460
+
461
+
462
+ ## == Creates a selection group input
463
+ ##
464
+ ## Creates the labels and an input field for a group selection
465
+ ##
466
+ ## ==== Default styles :
467
+ ##
468
+ ## * input field is set to *select_input* class unless *class* is provided in the args hash
469
+ ##
470
+ ## * label field is set to *select_label* class unless *class_label* is provided in the args hash
471
+ ##
472
+ ## ==== Error styles :
473
+ ##
474
+ ## If an error occurs then both class names will be appended with a *_error*
475
+ ##
476
+ ## You can override those by providing *class_error* and *class_label_error* params in the args hash.
477
+ ##
478
+ def select(label, name, values, options = {})
479
+ id = id_for(name)
480
+ multiple, size = options.values_at(:multiple, :size)
481
+
482
+ args = {:id => id}
483
+ args[:multiple] = 'multiple' if multiple
484
+ args[:size] = (size || multiple || 1).to_i
485
+ args[:name] = multiple ? "#{name}[]" : name
486
+ has_selected, selected = options.key?(:selected), options[:selected]
487
+ css_classes = get_css_classes_clean(name,options,'select_input','select_label')
488
+ @g.p do
489
+ label_for(id, label, name,:class=>css_classes[:label_class])
490
+ @g.select args do
491
+ values.each do |value, o_name|
492
+ o_name ||= value
493
+ o_args = {:value => value}
494
+ o_args[:selected] = 'selected' if has_selected && value == selected
495
+ o_args[:class] = css_classes[:input_class]
496
+ @g.option(o_args){ o_name }
497
+ end
498
+ end
499
+ end
500
+ end
501
+
502
+ ## == Converts to string
503
+ ##
504
+ ## Returns the string containing the HTML of the form
505
+ ##
506
+ def to_s
507
+ @g.to_s
508
+ end
509
+
510
+ private
511
+
512
+ ##
513
+ ## Handles the CSS classes for labels and input fields
514
+ ## managing the eventual errors style changes
515
+ ##
516
+ ## Returns a hash containing the following keys :
517
+ ##
518
+ ## :input_class => CSS class to apply on the input field
519
+ ## :label_class => CSS class to apply on the label field
520
+ ##
521
+ ## Parameters :
522
+ ##
523
+ ## name : name of the fields
524
+ ## options : hash of options passed to the field constructor
525
+ ## input_default : default style for input fields (default to text_input )
526
+ ## label_default : default style for labels ( defaults to text_label )
527
+ ##
528
+ def get_css_classes(name,options={},input_default='text_input',label_default='text_label',delete_errors=true)
529
+ ret = {}
530
+ ret[:input_class] = options[:class] ? options[:class] : input_default
531
+ ret[:label_class] = options[:class_label] ? options[:class_label] : label_default
532
+ error = delete_errors ? @form_errors.delete(name.to_s) : @form_errors[name.to_s]
533
+ if ( error )
534
+ ret[:input_class] = options[:class_error] ? options[:class_error] : "#{ret[:input_class]}_error"
535
+ ret[:label_class] = options[:class_label_error] ? options[:class_label_error] : "#{ret[:label_class]}_error"
536
+ end
537
+ return ret
538
+ end
539
+
540
+ ## shortcut : get css options and clean the used options in the hash
541
+ def get_css_classes_clean(name,options={},input_default='text_input',label_default='text_label',delete_errors=true)
542
+ ret=get_css_classes(name,options,input_default,label_default,delete_errors)
543
+ options.delete(:class_label)
544
+ options.delete(:class_label_error)
545
+ options.delete(:class_error)
546
+ return ret
547
+ end
548
+
549
+ ## creates the label for a given field
550
+ def label_for(id, value, name, options = {})
551
+ css_class = options[:class] ? options[:class] : 'label_text'
552
+ @g.label(value,:for=>id,:class=>css_class)
553
+ end
554
+
555
+ ## generates the id for a field name
556
+ def id_for(field_name)
557
+ if name = @form_args[:name]
558
+ "#{name}-#{field_name}".downcase.gsub(/_/, '-')
559
+ else
560
+ "form-#{field_name}".downcase.gsub(/_/, '-')
561
+ end
562
+ end
563
+ end
564
+ end
565
+ end
566
+ end
@@ -0,0 +1,2 @@
1
+ require 'ext/ramaze/helper/banana_form.rb'
2
+