1
+ module Rubaidh #:nodoc:
2
+ module FormHelper
3
+
4
+ # def self.included(base)
5
+ # base.alias_method_chain :fields_for, :fieldset
6
+ # end
7
+ #
8
+ # # Behaves just like the regular +fields_for+ with a little extra magic
9
+ # # juju in that it creates a fieldset around the fields inside.
10
+ # def fields_for_with_fieldset(object_name, *args, &block)
11
+ # options = args.last.is_a?(Hash) ? args.pop : {}
12
+ # object = args.first
13
+ # legend = options.delete(:legend) || object_name.to_s.humanize
14
+ # concat tag('fieldset', options, true), block.binding
15
+ # concat "<legend>#{legend}</legend>", block.binding
16
+ # fields_for_without_fieldset(object_name, object, options.merge(:builder => FormBuilder), &block)
17
+ # concat "</fieldset>", block.binding
18
+ # end
19
+
20
+ def label_for ( object_name , method , options = { } )
21
+ ActionView ::Helpers ::InstanceTag . new ( object_name , method , self , nil , options . delete ( :object ) ) . to_label_tag ( options )
22
+ end
23
+
24
+ def label_tag ( name , text , options = { } )
25
+ content_tag ( 'label' , text , { 'for' => name } . merge ( options . stringify_keys ) )
26
+ end
27
+
28
+ def fieldset ( options , builder , &block )
29
+ legend = options . delete ( :legend )
30
+ concat tag ( 'fieldset' , options , true ) , block . binding
31
+ concat "<legend>#{ legend } </legend>" , block . binding unless legend . blank?
32
+ block . call ( builder )
33
+ concat "</fieldset>" , block . binding
34
+ end
35
+
36
+ def grouped_collection_select ( object_name , method , collection , group_method , group_label_method , value_method , text_method , options = { } , html_options = { } )
37
+ ActionView ::Helpers ::InstanceTag . new ( object_name , method , self , nil , options . delete ( :object ) ) . to_grouped_collection_select_tag ( collection , group_method , group_label_method , value_method , text_method , options , html_options )
38
+ end
39
+ end
40
+
41
+ module InstanceTag #:nodoc:
42
+ def to_label_tag ( options = { } )
43
+ options = options . stringify_keys
44
+ add_default_name_and_id ( options )
45
+ options . delete ( 'name' )
46
+ options [ 'for' ] = options . delete ( 'id' )
47
+
48
+ text = options . delete ( 'label' ) || @method_name . humanize
49
+ text += "\n " + content_tag ( 'span' , '(required)' , :class => :required ) if options . delete ( 'required' )
50
+ description = options . delete ( 'description' )
51
+
52
+ label = content_tag 'label' , text , options
53
+
54
+ unless description . blank?
55
+ label += content_tag ( 'p' , description , { } )
56
+ end
57
+
58
+ label
59
+ end
60
+
61
+ def to_grouped_collection_select_tag ( collection , group_method , group_label_method , value_method , text_method , options , html_options )
62
+ html_options = html_options . stringify_keys
63
+ add_default_name_and_id ( html_options )
64
+ value = value ( object )
65
+ content_tag (
66
+ "select" ,
67
+ add_options (
68
+ option_groups_from_collection_for_select (
69
+ collection , group_method , group_label_method ,
70
+ value_method , text_method , value ) ,
71
+ options , value ) ,
72
+ html_options
73
+ )
74
+ end
75
+ end
76
+
77
+ module FormBuilderMethods #:nodoc:
78
+ def label_for ( method , options = { } )
79
+ @template . label_for ( @object_name , method , options . merge ( :object => @object ) )
80
+ end
81
+
82
+ # Implement a collection select for groups of options. See
83
+ # +options_from_collection_for_select+ for more information, but it's more
84
+ # or less the same as +collection_select+.
85
+ def grouped_collection_select ( method , collection , group_method , group_label_method , value_method , text_method , options = { } , html_options = { } )
86
+ @template . grouped_collection_select ( @object_name , method , collection , group_method , group_label_method , value_method , text_method , options . merge ( :object => @object ) , html_options )
87
+ end
88
+ end
89
+
90
+ class FormBuilder < ActionView ::Helpers ::FormBuilder #:nodoc:
91
+ ( ActionView ::Helpers ::FormHelper . instance_methods - %w( label_for hidden_field check_box radio_button form_for fields_for ) + %w( datetime_select date_select ) ) . each do |selector |
92
+ src = <<-end_src
93
+ def #{ selector } (method, options = {})
94
+ label_options = label_options_from_options(options)
95
+ label_for(method, label_options) + "\n " + super
96
+ end
97
+ end_src
98
+ class_eval src , __FILE__ , __LINE__
99
+ end
100
+
101
+ def select ( method , choices , options = { } , html_options = { } )
102
+ label_options = label_options_from_options ( options )
103
+ label_for ( method , label_options ) + "\n " + super
104
+ end
105
+
106
+ def collection_select ( method , collection , value_method , text_method , options = { } , html_options = { } )
107
+ label_options = label_options_from_options ( options )
108
+ label_method = method . to_s . gsub /_ids$/ , 's'
109
+
110
+ # Generate the correct name for HABTM relations and multi-select boxes.
111
+ html_options [ :name ] = "#{ object_name } [#{ method } ][]" if html_options [ :multiple ]
112
+
113
+ label_for ( label_method , label_options ) + "\n " + super
114
+ end
115
+
116
+ def grouped_collection_select ( method , collection , group_method , group_label_method , value_method , text_method , options = { } , html_options = { } )
117
+ label_options = label_options_from_options ( options )
118
+ label_method = method . to_s . gsub /_ids$/ , 's'
119
+
120
+ # Generate the correct name for HABTM relations and multi-select boxes.
121
+ html_options [ :name ] = "#{ object_name } [#{ method } ][]" if html_options [ :multiple ]
122
+
123
+ label_for ( label_method , label_options ) + "\n " + super
124
+ end
125
+
126
+ def check_box ( method , options = { } , checked_value = "1" , unchecked_value = "0" )
127
+ label_options = label_options_from_options ( options )
128
+ super + "\n " + label_for ( method , label_options )
129
+ end
130
+
131
+ def radio_button ( method , tag_value , options = { } )
132
+ label_options = label_options_from_options ( options )
133
+ super + "\n " + label_for ( method , label_options )
134
+ end
135
+
136
+ def fields_for ( object_name , object , builder = self . class , &proc )
137
+ @template . fields_for ( object_name , object , builder , &proc )
138
+ end
139
+
140
+ def fieldset ( options = { } , builder = self , &block )
141
+ @template . fieldset ( options , builder , &block )
142
+ end
143
+
144
+ private
145
+ def label_options_from_options ( options )
146
+ label_options = options . dup
147
+
148
+ # Remove the options from the main field which apply solely to the
149
+ # label.
150
+ [ :label , :description , :required ] . each do |v |
151
+ options . delete ( v )
152
+ end
153
+
154
+ # Tidy up the label options so they only have what's required.
155
+ label_options . reject do |k , v |
156
+ ![ :id , :label , :description , :required ] . include? ( k )
157
+ end
158
+ end
159
+ end
160
+ end
0 commit comments