simple_form 2.0.0 → 2.1.0
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/CHANGELOG.md +34 -231
- data/MIT-LICENSE +1 -1
- data/README.md +221 -159
- data/lib/generators/simple_form/install_generator.rb +14 -5
- data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +8 -42
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +45 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +26 -0
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -5
- data/lib/simple_form/action_view_extensions/builder.rb +46 -30
- data/lib/simple_form/action_view_extensions/builder.rb.orig +247 -0
- data/lib/simple_form/action_view_extensions/form_helper.rb +7 -9
- data/lib/simple_form/components/hints.rb +3 -2
- data/lib/simple_form/components/label_input.rb +1 -1
- data/lib/simple_form/components/labels.rb +1 -1
- data/lib/simple_form/components/maxlength.rb +1 -1
- data/lib/simple_form/components/min_max.rb +2 -1
- data/lib/simple_form/components/pattern.rb +1 -1
- data/lib/simple_form/components/readonly.rb +1 -1
- data/lib/simple_form/components.rb +12 -10
- data/lib/simple_form/error_notification.rb +1 -1
- data/lib/simple_form/form_builder.rb +18 -8
- data/lib/simple_form/form_builder.rb.orig +486 -0
- data/lib/simple_form/helpers/validators.rb +2 -2
- data/lib/simple_form/inputs/base.rb +33 -8
- data/lib/simple_form/inputs/boolean_input.rb +19 -5
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -6
- data/lib/simple_form/inputs/date_time_input.rb +0 -4
- data/lib/simple_form/inputs.rb +19 -17
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/version.rb.orig +7 -0
- data/lib/simple_form/wrappers/many.rb +5 -1
- data/lib/simple_form/wrappers/root.rb +4 -2
- data/lib/simple_form/wrappers/single.rb +6 -0
- data/lib/simple_form.rb +17 -8
- data/test/action_view_extensions/builder_test.rb +145 -66
- data/test/action_view_extensions/form_helper_test.rb +59 -20
- data/test/components/label_test.rb +34 -17
- data/test/form_builder/association_test.rb +19 -10
- data/test/form_builder/error_notification_test.rb +1 -1
- data/test/form_builder/general_test.rb +74 -12
- data/test/form_builder/hint_test.rb +15 -0
- data/test/form_builder/input_field_test.rb +45 -0
- data/test/form_builder/label_test.rb +6 -0
- data/test/form_builder/wrapper_test.rb +58 -4
- data/test/generators/simple_form_generator_test.rb +11 -1
- data/test/inputs/boolean_input_test.rb +39 -0
- data/test/inputs/datetime_input_test.rb +2 -2
- data/test/inputs/disabled_test.rb +51 -11
- data/test/inputs/discovery_test.rb +9 -1
- data/test/inputs/general_test.rb +58 -11
- data/test/inputs/grouped_collection_select_input_test.rb +15 -0
- data/test/inputs/numeric_input_test.rb +6 -0
- data/test/inputs/readonly_test.rb +51 -11
- data/test/inputs/string_input_test.rb +6 -0
- data/test/support/discovery_inputs.rb +6 -0
- data/test/support/misc_helpers.rb +41 -1
- data/test/support/models.rb +8 -4
- data/test/test_helper.rb +8 -6
- metadata +26 -13
- data/test/support/mock_response.rb +0 -14
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Use this setup block to configure all options available in SimpleForm.
|
|
2
|
+
SimpleForm.setup do |config|
|
|
3
|
+
config.wrappers :foundation, :class => :input, :hint_class => :field_with_hint, :error_class => :error do |b|
|
|
4
|
+
b.use :html5
|
|
5
|
+
b.use :placeholder
|
|
6
|
+
b.optional :maxlength
|
|
7
|
+
b.optional :pattern
|
|
8
|
+
b.optional :min_max
|
|
9
|
+
b.optional :readonly
|
|
10
|
+
b.use :label_input
|
|
11
|
+
b.use :error, :wrap_with => { :tag => :small }
|
|
12
|
+
|
|
13
|
+
# Uncomment the following line to enable hints. The line is commented out by default since Foundation
|
|
14
|
+
# does't provide styles for hints. You will need to provide your own CSS styles for hints.
|
|
15
|
+
# b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# CSS class for buttons
|
|
19
|
+
config.button_class = 'button'
|
|
20
|
+
|
|
21
|
+
# CSS class to add for error notification helper.
|
|
22
|
+
config.error_notification_class = 'alert-box alert'
|
|
23
|
+
|
|
24
|
+
# The default wrapper to be used by the FormBuilder.
|
|
25
|
+
config.default_wrapper = :foundation
|
|
26
|
+
end
|
|
@@ -9,16 +9,18 @@ en:
|
|
|
9
9
|
# When using html, text and mark won't be used.
|
|
10
10
|
# html: '<abbr title="required">*</abbr>'
|
|
11
11
|
error_notification:
|
|
12
|
-
default_message: "
|
|
12
|
+
default_message: "Please review the problems below:"
|
|
13
13
|
# Labels and hints examples
|
|
14
14
|
# labels:
|
|
15
|
-
#
|
|
15
|
+
# defaults:
|
|
16
|
+
# password: 'Password'
|
|
16
17
|
# user:
|
|
17
18
|
# new:
|
|
18
|
-
# email: 'E-mail
|
|
19
|
+
# email: 'E-mail to sign in.'
|
|
19
20
|
# edit:
|
|
20
21
|
# email: 'E-mail.'
|
|
21
22
|
# hints:
|
|
22
|
-
#
|
|
23
|
-
#
|
|
23
|
+
# defaults:
|
|
24
|
+
# username: 'User name to sign in.'
|
|
25
|
+
# password: 'No special characters, please.'
|
|
24
26
|
|
|
@@ -5,10 +5,9 @@ module SimpleForm
|
|
|
5
5
|
class BuilderBase #:nodoc:
|
|
6
6
|
attr_reader :object, :text, :value
|
|
7
7
|
|
|
8
|
-
def initialize(
|
|
9
|
-
|
|
10
|
-
@
|
|
11
|
-
@object_name = object_name
|
|
8
|
+
def initialize(form_builder, method_name, object, sanitized_attribute_name, text,
|
|
9
|
+
value, input_html_options)
|
|
10
|
+
@form_builder = form_builder
|
|
12
11
|
@method_name = method_name
|
|
13
12
|
@object = object
|
|
14
13
|
@sanitized_attribute_name = sanitized_attribute_name
|
|
@@ -18,7 +17,7 @@ module SimpleForm
|
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def label(label_html_options={}, &block)
|
|
21
|
-
@
|
|
20
|
+
@form_builder.label(@sanitized_attribute_name, @text, label_html_options, &block)
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
|
|
@@ -26,7 +25,7 @@ module SimpleForm
|
|
|
26
25
|
class RadioButtonBuilder < BuilderBase #:nodoc:
|
|
27
26
|
def radio_button(extra_html_options={})
|
|
28
27
|
html_options = extra_html_options.merge(@input_html_options)
|
|
29
|
-
@
|
|
28
|
+
@form_builder.radio_button(@method_name, @value, html_options)
|
|
30
29
|
end
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -34,7 +33,7 @@ module SimpleForm
|
|
|
34
33
|
class CheckBoxBuilder < BuilderBase #:nodoc:
|
|
35
34
|
def check_box(extra_html_options={})
|
|
36
35
|
html_options = extra_html_options.merge(@input_html_options)
|
|
37
|
-
@
|
|
36
|
+
@form_builder.check_box(@method_name, html_options, @value, nil)
|
|
38
37
|
end
|
|
39
38
|
end
|
|
40
39
|
|
|
@@ -93,7 +92,7 @@ module SimpleForm
|
|
|
93
92
|
rendered_collection = render_collection(
|
|
94
93
|
collection, value_method, text_method, options, html_options
|
|
95
94
|
) do |item, value, text, default_html_options|
|
|
96
|
-
builder =
|
|
95
|
+
builder = instantiate_collection_builder(RadioButtonBuilder, attribute, item, value, text, default_html_options)
|
|
97
96
|
|
|
98
97
|
if block_given?
|
|
99
98
|
yield builder
|
|
@@ -154,7 +153,8 @@ module SimpleForm
|
|
|
154
153
|
#
|
|
155
154
|
# * collection_wrapper_tag => the tag to wrap the entire collection.
|
|
156
155
|
#
|
|
157
|
-
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag
|
|
156
|
+
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option
|
|
157
|
+
# is ignored if the :collection_wrapper_tag option is blank.
|
|
158
158
|
#
|
|
159
159
|
# * item_wrapper_tag => the tag to wrap each item in the collection.
|
|
160
160
|
#
|
|
@@ -167,7 +167,7 @@ module SimpleForm
|
|
|
167
167
|
collection, value_method, text_method, options, html_options
|
|
168
168
|
) do |item, value, text, default_html_options|
|
|
169
169
|
default_html_options[:multiple] = true
|
|
170
|
-
builder =
|
|
170
|
+
builder = instantiate_collection_builder(CheckBoxBuilder, attribute, item, value, text, default_html_options)
|
|
171
171
|
|
|
172
172
|
if block_given?
|
|
173
173
|
yield builder
|
|
@@ -178,7 +178,7 @@ module SimpleForm
|
|
|
178
178
|
|
|
179
179
|
# Append a hidden field to make sure something will be sent back to the
|
|
180
180
|
# server if all checkboxes are unchecked.
|
|
181
|
-
hidden = template.hidden_field_tag("#{object_name}[#{attribute}][]", "", :id => nil)
|
|
181
|
+
hidden = @template.hidden_field_tag("#{object_name}[#{attribute}][]", "", :id => nil)
|
|
182
182
|
|
|
183
183
|
wrap_rendered_collection(rendered_collection + hidden, options)
|
|
184
184
|
end
|
|
@@ -194,7 +194,8 @@ module SimpleForm
|
|
|
194
194
|
# end
|
|
195
195
|
def simple_fields_for(*args, &block)
|
|
196
196
|
options = args.extract_options!
|
|
197
|
-
options[:wrapper]
|
|
197
|
+
options[:wrapper] = self.options[:wrapper] if options[:wrapper].nil?
|
|
198
|
+
options[:defaults] ||= self.options[:defaults]
|
|
198
199
|
|
|
199
200
|
if self.class < ActionView::Helpers::FormBuilder
|
|
200
201
|
options[:builder] ||= self.class
|
|
@@ -206,8 +207,8 @@ module SimpleForm
|
|
|
206
207
|
|
|
207
208
|
private
|
|
208
209
|
|
|
209
|
-
def
|
|
210
|
-
builder_class.new(
|
|
210
|
+
def instantiate_collection_builder(builder_class, attribute, item, value, text, html_options)
|
|
211
|
+
builder_class.new(self, attribute, item,
|
|
211
212
|
sanitize_attribute_name(attribute, value), text, value, html_options)
|
|
212
213
|
end
|
|
213
214
|
|
|
@@ -217,12 +218,13 @@ module SimpleForm
|
|
|
217
218
|
html_options = html_options.dup
|
|
218
219
|
|
|
219
220
|
[:checked, :selected, :disabled].each do |option|
|
|
220
|
-
|
|
221
|
+
current_option = options[option]
|
|
222
|
+
next if current_option.nil?
|
|
221
223
|
|
|
222
224
|
accept = if current_option.respond_to?(:call)
|
|
223
225
|
current_option.call(item)
|
|
224
226
|
else
|
|
225
|
-
Array(current_option).include?(value)
|
|
227
|
+
Array(current_option).map(&:to_s).include?(value.to_s)
|
|
226
228
|
end
|
|
227
229
|
|
|
228
230
|
if accept
|
|
@@ -275,34 +277,48 @@ end
|
|
|
275
277
|
module ActionView::Helpers
|
|
276
278
|
class FormBuilder
|
|
277
279
|
include SimpleForm::ActionViewExtensions::Builder
|
|
280
|
+
end
|
|
278
281
|
|
|
279
|
-
|
|
282
|
+
module FormOptionsHelper
|
|
283
|
+
# Override Rails options_from_collection_for_select to handle lambdas/procs in
|
|
280
284
|
# text and value methods, so it works the same way as collection_radio_buttons
|
|
281
285
|
# and collection_check_boxes in SimpleForm. If none of text/value methods is a
|
|
282
286
|
# callable object, then it just delegates back to original collection select.
|
|
283
|
-
#
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
# FIXME: remove when support only Rails 4.0 forward
|
|
288
|
+
# https://github.com/rails/rails/commit/9035324367526af0300477a58b6d3efc15d1a5a8
|
|
289
|
+
alias :original_options_from_collection_for_select :options_from_collection_for_select
|
|
290
|
+
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
|
|
286
291
|
if value_method.respond_to?(:call) || text_method.respond_to?(:call)
|
|
287
292
|
collection = collection.map do |item|
|
|
288
293
|
value = value_for_collection(item, value_method)
|
|
289
294
|
text = value_for_collection(item, text_method)
|
|
290
295
|
|
|
291
|
-
|
|
292
|
-
disabled = value if default_html_options[:disabled]
|
|
293
|
-
selected = value if default_html_options[:selected]
|
|
294
|
-
|
|
295
|
-
[value, text, selected, disabled]
|
|
296
|
+
[value, text]
|
|
296
297
|
end
|
|
297
298
|
|
|
298
|
-
[:disabled, :selected].each do |option|
|
|
299
|
-
option_value = collection.map(&:pop).compact
|
|
300
|
-
options[option] = option_value if option_value.present?
|
|
301
|
-
end
|
|
302
299
|
value_method, text_method = :first, :last
|
|
300
|
+
selected = extract_selected_and_disabled_and_call_procs selected, collection
|
|
303
301
|
end
|
|
304
302
|
|
|
305
|
-
|
|
303
|
+
original_options_from_collection_for_select collection, value_method, text_method, selected
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
private
|
|
307
|
+
|
|
308
|
+
def extract_selected_and_disabled_and_call_procs(selected, collection)
|
|
309
|
+
selected, disabled = extract_selected_and_disabled selected
|
|
310
|
+
selected_disabled = { :selected => selected, :disabled => disabled }
|
|
311
|
+
|
|
312
|
+
selected_disabled.each do |key, check|
|
|
313
|
+
if check.is_a? Proc
|
|
314
|
+
values = collection.map { |option| option.first if check.call(option.first) }
|
|
315
|
+
selected_disabled[key] = values
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def value_for_collection(item, value) #:nodoc:
|
|
321
|
+
value.respond_to?(:call) ? value.call(item) : item.send(value)
|
|
306
322
|
end
|
|
307
323
|
end
|
|
308
324
|
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module ActionViewExtensions
|
|
3
|
+
# A collection of methods required by simple_form but added to rails default form.
|
|
4
|
+
# This means that you can use such methods outside simple_form context.
|
|
5
|
+
module Builder
|
|
6
|
+
|
|
7
|
+
# Wrapper for using SimpleForm inside a default rails form.
|
|
8
|
+
# Example:
|
|
9
|
+
#
|
|
10
|
+
# form_for @user do |f|
|
|
11
|
+
# f.simple_fields_for :posts do |posts_form|
|
|
12
|
+
# # Here you have all simple_form methods available
|
|
13
|
+
# posts_form.input :title
|
|
14
|
+
# end
|
|
15
|
+
# end
|
|
16
|
+
def simple_fields_for(*args, &block)
|
|
17
|
+
options = args.extract_options!
|
|
18
|
+
options[:wrapper] = self.options[:wrapper] if options[:wrapper].nil?
|
|
19
|
+
options[:defaults] ||= self.options[:defaults]
|
|
20
|
+
|
|
21
|
+
if self.class < ActionView::Helpers::FormBuilder
|
|
22
|
+
options[:builder] ||= self.class
|
|
23
|
+
else
|
|
24
|
+
options[:builder] ||= SimpleForm::FormBuilder
|
|
25
|
+
end
|
|
26
|
+
fields_for(*(args << options), &block)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module SimpleForm
|
|
33
|
+
module Tags
|
|
34
|
+
module CollectionExtensions
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def render_collection
|
|
38
|
+
item_wrapper_tag = @options.fetch(:item_wrapper_tag, :span)
|
|
39
|
+
item_wrapper_class = @options[:item_wrapper_class]
|
|
40
|
+
|
|
41
|
+
@collection.map do |item|
|
|
42
|
+
value = value_for_collection(item, @value_method)
|
|
43
|
+
text = value_for_collection(item, @text_method)
|
|
44
|
+
default_html_options = default_html_options_for_collection(item, value)
|
|
45
|
+
|
|
46
|
+
rendered_item = yield item, value, text, default_html_options
|
|
47
|
+
|
|
48
|
+
item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, :class => item_wrapper_class) : rendered_item
|
|
49
|
+
end.join.html_safe
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def wrap_rendered_collection(collection)
|
|
53
|
+
wrapper_tag = @options[:collection_wrapper_tag]
|
|
54
|
+
|
|
55
|
+
if wrapper_tag
|
|
56
|
+
wrapper_class = @options[:collection_wrapper_class]
|
|
57
|
+
@template_object.content_tag(wrapper_tag, collection, :class => wrapper_class)
|
|
58
|
+
else
|
|
59
|
+
collection
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class CollectionRadioButtons < ActionView::Helpers::Tags::CollectionRadioButtons
|
|
65
|
+
include CollectionExtensions
|
|
66
|
+
|
|
67
|
+
def render
|
|
68
|
+
wrap_rendered_collection(super)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def render_component(builder)
|
|
74
|
+
builder.radio_button + builder.label(:class => "collection_radio_buttons")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCheckBoxes
|
|
79
|
+
include CollectionExtensions
|
|
80
|
+
|
|
81
|
+
def render
|
|
82
|
+
wrap_rendered_collection(super)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def render_component(builder)
|
|
88
|
+
builder.check_box + builder.label(:class => "collection_check_boxes")
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
module ActionView::Helpers
|
|
95
|
+
class FormBuilder
|
|
96
|
+
include SimpleForm::ActionViewExtensions::Builder
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
<<<<<<< HEAD
|
|
100
|
+
# Create a collection of radio inputs for the attribute. Basically this
|
|
101
|
+
# helper will create a radio input associated with a label for each
|
|
102
|
+
# text/value option in the collection, using value_method and text_method
|
|
103
|
+
# to convert these text/value. You can give a symbol or a proc to both
|
|
104
|
+
# value_method and text_method, that will be evaluated for each item in
|
|
105
|
+
# the collection.
|
|
106
|
+
#
|
|
107
|
+
# == Examples
|
|
108
|
+
#
|
|
109
|
+
# form_for @user do |f|
|
|
110
|
+
# f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
|
111
|
+
# end
|
|
112
|
+
#
|
|
113
|
+
# <input id="user_options_true" name="user[options]" type="radio" value="true" />
|
|
114
|
+
# <label class="collection_radio_buttons" for="user_options_true">Yes</label>
|
|
115
|
+
# <input id="user_options_false" name="user[options]" type="radio" value="false" />
|
|
116
|
+
# <label class="collection_radio_buttons" for="user_options_false">No</label>
|
|
117
|
+
#
|
|
118
|
+
# It is also possible to give a block that should generate the radio +
|
|
119
|
+
# label. To wrap the radio with the label, for instance:
|
|
120
|
+
#
|
|
121
|
+
# form_for @user do |f|
|
|
122
|
+
# f.collection_radio_buttons(
|
|
123
|
+
# :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
|
124
|
+
# ) do |b|
|
|
125
|
+
# b.label { b.radio_button + b.text }
|
|
126
|
+
# end
|
|
127
|
+
# end
|
|
128
|
+
#
|
|
129
|
+
# == Options
|
|
130
|
+
#
|
|
131
|
+
# Collection radio accepts some extra options:
|
|
132
|
+
#
|
|
133
|
+
# * checked => the value that should be checked initially.
|
|
134
|
+
#
|
|
135
|
+
# * disabled => the value or values that should be disabled. Accepts a single
|
|
136
|
+
# item or an array of items.
|
|
137
|
+
#
|
|
138
|
+
# * collection_wrapper_tag => the tag to wrap the entire collection.
|
|
139
|
+
#
|
|
140
|
+
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag
|
|
141
|
+
#
|
|
142
|
+
# * item_wrapper_tag => the tag to wrap each item in the collection.
|
|
143
|
+
#
|
|
144
|
+
# * item_wrapper_class => the CSS class to use for item_wrapper_tag
|
|
145
|
+
#
|
|
146
|
+
# * a block => to generate the label + radio or any other component.
|
|
147
|
+
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
148
|
+
SimpleForm::Tags::CollectionRadioButtons.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
|
|
149
|
+
=======
|
|
150
|
+
module FormOptionsHelper
|
|
151
|
+
# Override Rails options_from_collection_for_select to handle lambdas/procs in
|
|
152
|
+
# text and value methods, so it works the same way as collection_radio_buttons
|
|
153
|
+
# and collection_check_boxes in SimpleForm. If none of text/value methods is a
|
|
154
|
+
# callable object, then it just delegates back to original collection select.
|
|
155
|
+
# FIXME: remove when support only Rails 4.0 forward
|
|
156
|
+
# https://github.com/rails/rails/commit/9035324367526af0300477a58b6d3efc15d1a5a8
|
|
157
|
+
alias :original_options_from_collection_for_select :options_from_collection_for_select
|
|
158
|
+
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
|
|
159
|
+
if value_method.respond_to?(:call) || text_method.respond_to?(:call)
|
|
160
|
+
collection = collection.map do |item|
|
|
161
|
+
value = value_for_collection(item, value_method)
|
|
162
|
+
text = value_for_collection(item, text_method)
|
|
163
|
+
|
|
164
|
+
[value, text]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
value_method, text_method = :first, :last
|
|
168
|
+
selected = extract_selected_and_disabled_and_call_procs selected, collection
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
original_options_from_collection_for_select collection, value_method, text_method, selected
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
private
|
|
175
|
+
|
|
176
|
+
def extract_selected_and_disabled_and_call_procs(selected, collection)
|
|
177
|
+
selected, disabled = extract_selected_and_disabled selected
|
|
178
|
+
selected_disabled = { :selected => selected, :disabled => disabled }
|
|
179
|
+
|
|
180
|
+
selected_disabled.each do |key, check|
|
|
181
|
+
if check.is_a? Proc
|
|
182
|
+
values = collection.map { |option| option.first if check.call(option.first) }
|
|
183
|
+
selected_disabled[key] = values
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def value_for_collection(item, value) #:nodoc:
|
|
189
|
+
value.respond_to?(:call) ? value.call(item) : item.send(value)
|
|
190
|
+
>>>>>>> master
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Creates a collection of check boxes for each item in the collection,
|
|
194
|
+
# associated with a clickable label. Use value_method and text_method to
|
|
195
|
+
# convert items in the collection for use as text/value in check boxes.
|
|
196
|
+
# You can give a symbol or a proc to both value_method and text_method,
|
|
197
|
+
# that will be evaluated for each item in the collection.
|
|
198
|
+
#
|
|
199
|
+
# == Examples
|
|
200
|
+
#
|
|
201
|
+
# form_for @user do |f|
|
|
202
|
+
# f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
|
203
|
+
# end
|
|
204
|
+
#
|
|
205
|
+
# <input name="user[options][]" type="hidden" value="" />
|
|
206
|
+
# <input id="user_options_true" name="user[options][]" type="checkbox" value="true" />
|
|
207
|
+
# <label class="collection_check_boxes" for="user_options_true">Yes</label>
|
|
208
|
+
# <input name="user[options][]" type="hidden" value="" />
|
|
209
|
+
# <input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
|
|
210
|
+
# <label class="collection_check_boxes" for="user_options_false">No</label>
|
|
211
|
+
#
|
|
212
|
+
# It is also possible to give a block that should generate the check box +
|
|
213
|
+
# label. To wrap the check box with the label, for instance:
|
|
214
|
+
#
|
|
215
|
+
# form_for @user do |f|
|
|
216
|
+
# f.collection_check_boxes(
|
|
217
|
+
# :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
|
218
|
+
# ) do |b|
|
|
219
|
+
# b.label { b.check_box + b.text }
|
|
220
|
+
# end
|
|
221
|
+
# end
|
|
222
|
+
#
|
|
223
|
+
# == Options
|
|
224
|
+
#
|
|
225
|
+
# Collection check box accepts some extra options:
|
|
226
|
+
#
|
|
227
|
+
# * checked => the value or values that should be checked initially. Accepts
|
|
228
|
+
# a single item or an array of items. It overrides existing associations.
|
|
229
|
+
#
|
|
230
|
+
# * disabled => the value or values that should be disabled. Accepts a single
|
|
231
|
+
# item or an array of items.
|
|
232
|
+
#
|
|
233
|
+
# * collection_wrapper_tag => the tag to wrap the entire collection.
|
|
234
|
+
#
|
|
235
|
+
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option
|
|
236
|
+
# is ignored if the :collection_wrapper_tag option is blank.
|
|
237
|
+
#
|
|
238
|
+
# * item_wrapper_tag => the tag to wrap each item in the collection.
|
|
239
|
+
#
|
|
240
|
+
# * item_wrapper_class => the CSS class to use for item_wrapper_tag
|
|
241
|
+
#
|
|
242
|
+
# * a block => to generate the label + check box or any other component.
|
|
243
|
+
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
244
|
+
SimpleForm::Tags::CollectionCheckBoxes.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
@@ -9,10 +9,6 @@ module SimpleForm
|
|
|
9
9
|
# end
|
|
10
10
|
#
|
|
11
11
|
module FormHelper
|
|
12
|
-
# based on what is done in formtastic
|
|
13
|
-
# http://github.com/justinfrench/formtastic/blob/master/lib/formtastic.rb#L1706
|
|
14
|
-
@@default_field_error_proc = nil
|
|
15
|
-
|
|
16
12
|
# Override the default ActiveRecordHelper behaviour of wrapping the input.
|
|
17
13
|
# This gets taken care of semantically by adding an error class to the wrapper tag
|
|
18
14
|
# containing the input.
|
|
@@ -46,11 +42,13 @@ module SimpleForm
|
|
|
46
42
|
private
|
|
47
43
|
|
|
48
44
|
def with_simple_form_field_error_proc
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
default_field_error_proc = ::ActionView::Base.field_error_proc
|
|
46
|
+
begin
|
|
47
|
+
::ActionView::Base.field_error_proc = FIELD_ERROR_PROC
|
|
48
|
+
yield
|
|
49
|
+
ensure
|
|
50
|
+
::ActionView::Base.field_error_proc = default_field_error_proc
|
|
51
|
+
end
|
|
54
52
|
end
|
|
55
53
|
|
|
56
54
|
def simple_form_css_class(record, options)
|
|
@@ -5,12 +5,13 @@ module SimpleForm
|
|
|
5
5
|
def hint
|
|
6
6
|
@hint ||= begin
|
|
7
7
|
hint = options[:hint]
|
|
8
|
-
hint.is_a?(String) ? hint : translate(:hints)
|
|
8
|
+
hint_content = hint.is_a?(String) ? hint : translate(:hints)
|
|
9
|
+
hint_content.html_safe if hint_content
|
|
9
10
|
end
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def has_hint?
|
|
13
|
-
hint.present?
|
|
14
|
+
options[:hint] != false && hint.present?
|
|
14
15
|
end
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -7,6 +7,7 @@ module SimpleForm
|
|
|
7
7
|
input_html_options[:min] ||= minimum_value(validator_options)
|
|
8
8
|
input_html_options[:max] ||= maximum_value(validator_options)
|
|
9
9
|
end
|
|
10
|
+
nil
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
private
|
|
@@ -32,7 +33,7 @@ module SimpleForm
|
|
|
32
33
|
end
|
|
33
34
|
|
|
34
35
|
def find_numericality_validator
|
|
35
|
-
find_validator(
|
|
36
|
+
find_validator(:numericality)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def evaluate_numericality_validator_option(option)
|
|
@@ -15,7 +15,7 @@ module SimpleForm
|
|
|
15
15
|
def readonly_attribute?
|
|
16
16
|
object.class.respond_to?(:readonly_attributes) &&
|
|
17
17
|
object.persisted? &&
|
|
18
|
-
object.class.readonly_attributes.include?(attribute_name)
|
|
18
|
+
object.class.readonly_attributes.include?(attribute_name.to_s)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -6,15 +6,17 @@ module SimpleForm
|
|
|
6
6
|
# to the input in order to be enabled. On the other hand, things like
|
|
7
7
|
# hints can generate output automatically by doing I18n lookups.
|
|
8
8
|
module Components
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
autoload :
|
|
12
|
-
autoload :
|
|
13
|
-
autoload :
|
|
14
|
-
autoload :
|
|
15
|
-
autoload :
|
|
16
|
-
autoload :
|
|
17
|
-
autoload :
|
|
18
|
-
autoload :
|
|
9
|
+
extend ActiveSupport::Autoload
|
|
10
|
+
|
|
11
|
+
autoload :Errors
|
|
12
|
+
autoload :Hints
|
|
13
|
+
autoload :HTML5
|
|
14
|
+
autoload :LabelInput
|
|
15
|
+
autoload :Labels
|
|
16
|
+
autoload :MinMax
|
|
17
|
+
autoload :Maxlength
|
|
18
|
+
autoload :Pattern
|
|
19
|
+
autoload :Placeholders
|
|
20
|
+
autoload :Readonly
|
|
19
21
|
end
|
|
20
22
|
end
|
|
@@ -41,7 +41,7 @@ module SimpleForm
|
|
|
41
41
|
lookups = []
|
|
42
42
|
lookups << :"#{object_name}"
|
|
43
43
|
lookups << :default_message
|
|
44
|
-
lookups << "
|
|
44
|
+
lookups << "Please review the problems below:"
|
|
45
45
|
I18n.t(lookups.shift, :scope => :"simple_form.error_notification", :default => lookups)
|
|
46
46
|
end
|
|
47
47
|
end
|