simple_form 2.1.0 → 3.0.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.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -32
- data/README.md +161 -119
- data/lib/generators/simple_form/install_generator.rb +3 -3
- data/lib/generators/simple_form/templates/README +1 -1
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +16 -13
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +14 -14
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +3 -3
- data/lib/simple_form/action_view_extensions/builder.rb +1 -319
- data/lib/simple_form/action_view_extensions/form_helper.rb +2 -9
- data/lib/simple_form/components/html5.rb +5 -2
- data/lib/simple_form/components/labels.rb +3 -3
- data/lib/simple_form/components/maxlength.rb +1 -8
- data/lib/simple_form/components/pattern.rb +2 -2
- data/lib/simple_form/components.rb +1 -1
- data/lib/simple_form/error_notification.rb +2 -2
- data/lib/simple_form/form_builder.rb +155 -51
- data/lib/simple_form/helpers.rb +1 -1
- data/lib/simple_form/inputs/base.rb +6 -6
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +6 -4
- data/lib/simple_form/inputs/collection_input.rb +6 -6
- data/lib/simple_form/inputs/date_time_input.rb +1 -1
- data/lib/simple_form/inputs/numeric_input.rb +0 -6
- data/lib/simple_form/inputs/password_input.rb +0 -1
- data/lib/simple_form/inputs/string_input.rb +0 -1
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +62 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers/builder.rb +5 -29
- data/lib/simple_form/wrappers/many.rb +1 -1
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers.rb +1 -1
- data/lib/simple_form.rb +43 -47
- data/test/action_view_extensions/builder_test.rb +78 -92
- data/test/action_view_extensions/form_helper_test.rb +25 -16
- data/test/components/label_test.rb +46 -46
- data/test/form_builder/association_test.rb +47 -29
- data/test/form_builder/button_test.rb +4 -4
- data/test/form_builder/error_notification_test.rb +8 -8
- data/test/form_builder/error_test.rb +12 -12
- data/test/form_builder/general_test.rb +71 -52
- data/test/form_builder/hint_test.rb +22 -22
- data/test/form_builder/input_field_test.rb +29 -12
- data/test/form_builder/label_test.rb +7 -7
- data/test/form_builder/wrapper_test.rb +21 -21
- data/test/inputs/boolean_input_test.rb +35 -23
- data/test/inputs/collection_check_boxes_input_test.rb +66 -55
- data/test/inputs/collection_radio_buttons_input_test.rb +81 -79
- data/test/inputs/collection_select_input_test.rb +76 -45
- data/test/inputs/datetime_input_test.rb +17 -11
- data/test/inputs/disabled_test.rb +10 -10
- data/test/inputs/discovery_test.rb +4 -4
- data/test/inputs/file_input_test.rb +1 -1
- data/test/inputs/general_test.rb +28 -12
- data/test/inputs/grouped_collection_select_input_test.rb +33 -20
- data/test/inputs/hidden_input_test.rb +3 -2
- data/test/inputs/numeric_input_test.rb +3 -3
- data/test/inputs/priority_input_test.rb +9 -3
- data/test/inputs/readonly_test.rb +12 -12
- data/test/inputs/required_test.rb +5 -5
- data/test/inputs/string_input_test.rb +15 -25
- data/test/inputs/text_input_test.rb +1 -1
- data/test/support/misc_helpers.rb +46 -24
- data/test/support/mock_controller.rb +6 -6
- data/test/support/models.rb +80 -62
- data/test/test_helper.rb +17 -34
- metadata +31 -29
- data/lib/simple_form/core_ext/hash.rb +0 -16
@@ -1,5 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'active_support/core_ext/object/deep_dup'
|
2
2
|
require 'simple_form/map_type'
|
3
|
+
require 'simple_form/tags'
|
3
4
|
|
4
5
|
module SimpleForm
|
5
6
|
class FormBuilder < ActionView::Helpers::FormBuilder
|
@@ -7,26 +8,28 @@ module SimpleForm
|
|
7
8
|
|
8
9
|
# When action is create or update, we still should use new and edit
|
9
10
|
ACTIONS = {
|
10
|
-
:
|
11
|
-
:
|
11
|
+
create: :new,
|
12
|
+
update: :edit
|
12
13
|
}
|
13
14
|
|
15
|
+
ATTRIBUTE_COMPONENTS = [:html5, :min_max, :maxlength, :placeholder, :pattern, :readonly]
|
16
|
+
|
14
17
|
extend MapType
|
15
18
|
include SimpleForm::Inputs
|
16
19
|
|
17
|
-
map_type :text, :
|
18
|
-
map_type :file, :
|
19
|
-
map_type :string, :email, :search, :tel, :url, :
|
20
|
-
map_type :password, :
|
21
|
-
map_type :integer, :decimal, :float, :
|
22
|
-
map_type :range, :
|
23
|
-
map_type :check_boxes, :
|
24
|
-
map_type :radio_buttons, :
|
25
|
-
map_type :select, :
|
26
|
-
map_type :grouped_select, :
|
27
|
-
map_type :date, :time, :datetime, :
|
28
|
-
map_type :country, :time_zone, :
|
29
|
-
map_type :boolean, :
|
20
|
+
map_type :text, to: SimpleForm::Inputs::TextInput
|
21
|
+
map_type :file, to: SimpleForm::Inputs::FileInput
|
22
|
+
map_type :string, :email, :search, :tel, :url, to: SimpleForm::Inputs::StringInput
|
23
|
+
map_type :password, to: SimpleForm::Inputs::PasswordInput
|
24
|
+
map_type :integer, :decimal, :float, to: SimpleForm::Inputs::NumericInput
|
25
|
+
map_type :range, to: SimpleForm::Inputs::RangeInput
|
26
|
+
map_type :check_boxes, to: SimpleForm::Inputs::CollectionCheckBoxesInput
|
27
|
+
map_type :radio_buttons, to: SimpleForm::Inputs::CollectionRadioButtonsInput
|
28
|
+
map_type :select, to: SimpleForm::Inputs::CollectionSelectInput
|
29
|
+
map_type :grouped_select, to: SimpleForm::Inputs::GroupedCollectionSelectInput
|
30
|
+
map_type :date, :time, :datetime, to: SimpleForm::Inputs::DateTimeInput
|
31
|
+
map_type :country, :time_zone, to: SimpleForm::Inputs::PriorityInput
|
32
|
+
map_type :boolean, to: SimpleForm::Inputs::BooleanInput
|
30
33
|
|
31
34
|
def self.discovery_cache
|
32
35
|
@discovery_cache ||= {}
|
@@ -48,7 +51,7 @@ module SimpleForm
|
|
48
51
|
#
|
49
52
|
# # Imagine @user has error "can't be blank" on name
|
50
53
|
# simple_form_for @user do |f|
|
51
|
-
# f.input :name, :
|
54
|
+
# f.input :name, hint: 'My hint'
|
52
55
|
# end
|
53
56
|
#
|
54
57
|
# This is the output html (only the input portion, not the form):
|
@@ -57,7 +60,7 @@ module SimpleForm
|
|
57
60
|
# <abbr title="required">*</abbr> Super User Name!
|
58
61
|
# </label>
|
59
62
|
# <input class="string required" id="user_name" maxlength="100"
|
60
|
-
# name="user[name]"
|
63
|
+
# name="user[name]" type="text" value="Carlos" />
|
61
64
|
# <span class="hint">My hint</span>
|
62
65
|
# <span class="error">can't be blank</span>
|
63
66
|
#
|
@@ -66,15 +69,15 @@ module SimpleForm
|
|
66
69
|
#
|
67
70
|
# You have some options for the input to enable/disable some functions:
|
68
71
|
#
|
69
|
-
# :
|
72
|
+
# as: allows you to define the input type you want, for instance you
|
70
73
|
# can use it to generate a text field for a date column.
|
71
74
|
#
|
72
|
-
# :
|
75
|
+
# required: defines whether this attribute is required or not. True
|
73
76
|
# by default.
|
74
77
|
#
|
75
78
|
# The fact SimpleForm is built in components allow the interface to be unified.
|
76
79
|
# So, for instance, if you need to disable :hint for a given input, you can pass
|
77
|
-
# :
|
80
|
+
# hint: false. The same works for :error, :label and :wrapper.
|
78
81
|
#
|
79
82
|
# Besides the html for any component can be changed. So, if you want to change
|
80
83
|
# the label html you just need to give a hash to :label_html. To configure the
|
@@ -85,18 +88,18 @@ module SimpleForm
|
|
85
88
|
# Some inputs, as datetime, time and select allow you to give extra options, like
|
86
89
|
# prompt and/or include blank. Such options are given in plainly:
|
87
90
|
#
|
88
|
-
# f.input :created_at, :
|
91
|
+
# f.input :created_at, include_blank: true
|
89
92
|
#
|
90
93
|
# == Collection
|
91
94
|
#
|
92
95
|
# When playing with collections (:radio_buttons, :check_boxes and :select
|
93
96
|
# inputs), you have three extra options:
|
94
97
|
#
|
95
|
-
# :
|
98
|
+
# collection: use to determine the collection to generate the radio or select
|
96
99
|
#
|
97
|
-
# :
|
100
|
+
# label_method: the method to apply on the array collection to get the label
|
98
101
|
#
|
99
|
-
# :
|
102
|
+
# value_method: the method to apply on the array collection to get the value
|
100
103
|
#
|
101
104
|
# == Priority
|
102
105
|
#
|
@@ -130,14 +133,14 @@ module SimpleForm
|
|
130
133
|
# This is the output html (only the input portion, not the form):
|
131
134
|
#
|
132
135
|
# <input class="string required" id="user_name" maxlength="100"
|
133
|
-
# name="user[name]"
|
136
|
+
# name="user[name]" type="text" value="Carlos" />
|
134
137
|
#
|
135
138
|
def input_field(attribute_name, options={})
|
136
139
|
options = options.dup
|
137
|
-
options[:input_html] = options.except(:as, :collection, :label_method, :value_method)
|
140
|
+
options[:input_html] = options.except(:as, :collection, :label_method, :value_method, *ATTRIBUTE_COMPONENTS)
|
138
141
|
options = @defaults.deep_dup.deep_merge(options) if @defaults
|
139
142
|
|
140
|
-
SimpleForm::Wrappers::Root.new(
|
143
|
+
SimpleForm::Wrappers::Root.new(ATTRIBUTE_COMPONENTS + [:input], wrapper: false).render find_input(attribute_name, options)
|
141
144
|
end
|
142
145
|
|
143
146
|
# Helper for dealing with association selects/radios, generating the
|
@@ -151,7 +154,7 @@ module SimpleForm
|
|
151
154
|
# f.association :company # Company.all
|
152
155
|
# end
|
153
156
|
#
|
154
|
-
# f.association :company, :
|
157
|
+
# f.association :company, collection: Company.all(order: 'name')
|
155
158
|
# # Same as using :order option, but overriding collection
|
156
159
|
#
|
157
160
|
# == Block
|
@@ -166,6 +169,8 @@ module SimpleForm
|
|
166
169
|
#
|
167
170
|
# From the options above, only :collection can also be supplied.
|
168
171
|
#
|
172
|
+
# Please note that the association helper is currently only tested with Active Record. Depending on the ORM you are using your mileage may vary.
|
173
|
+
#
|
169
174
|
def association(association, options={}, &block)
|
170
175
|
options = options.dup
|
171
176
|
|
@@ -179,7 +184,9 @@ module SimpleForm
|
|
179
184
|
|
180
185
|
options[:as] ||= :select
|
181
186
|
options[:collection] ||= options.fetch(:collection) {
|
182
|
-
reflection.
|
187
|
+
conditions = reflection.options[:conditions]
|
188
|
+
conditions = conditions.call if conditions.respond_to?(:call)
|
189
|
+
reflection.klass.where(conditions).order(reflection.options[:order])
|
183
190
|
}
|
184
191
|
|
185
192
|
attribute = case reflection.macro
|
@@ -190,7 +197,6 @@ module SimpleForm
|
|
190
197
|
else
|
191
198
|
if options[:as] == :select
|
192
199
|
html_options = options[:input_html] ||= {}
|
193
|
-
html_options[:size] ||= 5
|
194
200
|
html_options[:multiple] = true unless html_options.key?(:multiple)
|
195
201
|
end
|
196
202
|
|
@@ -203,7 +209,7 @@ module SimpleForm
|
|
203
209
|
:"#{reflection.name.to_s.singularize}_ids"
|
204
210
|
end
|
205
211
|
|
206
|
-
input(attribute, options.merge(:
|
212
|
+
input(attribute, options.merge(reflection: reflection))
|
207
213
|
end
|
208
214
|
|
209
215
|
# Creates a button:
|
@@ -216,8 +222,7 @@ module SimpleForm
|
|
216
222
|
# button implementation (3.2 forward (to delegate to the original when
|
217
223
|
# calling `f.button :button`.
|
218
224
|
#
|
219
|
-
|
220
|
-
alias_method :button_button, :button if method_defined?(:button)
|
225
|
+
alias_method :button_button, :button
|
221
226
|
def button(type, *args, &block)
|
222
227
|
options = args.extract_options!.dup
|
223
228
|
options[:class] = [SimpleForm.button_class, options[:class]].compact
|
@@ -235,7 +240,7 @@ module SimpleForm
|
|
235
240
|
# == Examples
|
236
241
|
#
|
237
242
|
# f.error :name
|
238
|
-
# f.error :name, :
|
243
|
+
# f.error :name, id: "cool_error"
|
239
244
|
#
|
240
245
|
def error(attribute_name, options={})
|
241
246
|
options = options.dup
|
@@ -273,7 +278,7 @@ module SimpleForm
|
|
273
278
|
# == Examples
|
274
279
|
#
|
275
280
|
# f.hint :name # Do I18n lookup
|
276
|
-
# f.hint :name, :
|
281
|
+
# f.hint :name, id: "cool_hint"
|
277
282
|
# f.hint "Don't forget to accept this"
|
278
283
|
#
|
279
284
|
def hint(attribute_name, options={})
|
@@ -300,10 +305,10 @@ module SimpleForm
|
|
300
305
|
#
|
301
306
|
# f.label :name # Do I18n lookup
|
302
307
|
# f.label :name, "Name" # Same behavior as Rails, do not add required tag
|
303
|
-
# f.label :name, :
|
308
|
+
# f.label :name, label: "Name" # Same as above, but adds required tag
|
304
309
|
#
|
305
|
-
# f.label :name, :
|
306
|
-
# f.label :name, :
|
310
|
+
# f.label :name, required: false
|
311
|
+
# f.label :name, id: "cool_label"
|
307
312
|
#
|
308
313
|
def label(attribute_name, *args)
|
309
314
|
return super if args.first.is_a?(String) || block_given?
|
@@ -324,13 +329,118 @@ module SimpleForm
|
|
324
329
|
# == Examples
|
325
330
|
#
|
326
331
|
# f.error_notification
|
327
|
-
# f.error_notification :
|
328
|
-
# f.error_notification :
|
332
|
+
# f.error_notification message: 'Something went wrong'
|
333
|
+
# f.error_notification id: 'user_error_message', class: 'form_error'
|
329
334
|
#
|
330
335
|
def error_notification(options={})
|
331
336
|
SimpleForm::ErrorNotification.new(self, options).render
|
332
337
|
end
|
333
338
|
|
339
|
+
# Create a collection of radio inputs for the attribute. Basically this
|
340
|
+
# helper will create a radio input associated with a label for each
|
341
|
+
# text/value option in the collection, using value_method and text_method
|
342
|
+
# to convert these text/value. You can give a symbol or a proc to both
|
343
|
+
# value_method and text_method, that will be evaluated for each item in
|
344
|
+
# the collection.
|
345
|
+
#
|
346
|
+
# == Examples
|
347
|
+
#
|
348
|
+
# form_for @user do |f|
|
349
|
+
# f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
350
|
+
# end
|
351
|
+
#
|
352
|
+
# <input id="user_options_true" name="user[options]" type="radio" value="true" />
|
353
|
+
# <label class="collection_radio_buttons" for="user_options_true">Yes</label>
|
354
|
+
# <input id="user_options_false" name="user[options]" type="radio" value="false" />
|
355
|
+
# <label class="collection_radio_buttons" for="user_options_false">No</label>
|
356
|
+
#
|
357
|
+
# It is also possible to give a block that should generate the radio +
|
358
|
+
# label. To wrap the radio with the label, for instance:
|
359
|
+
#
|
360
|
+
# form_for @user do |f|
|
361
|
+
# f.collection_radio_buttons(
|
362
|
+
# :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
363
|
+
# ) do |b|
|
364
|
+
# b.label { b.radio_button + b.text }
|
365
|
+
# end
|
366
|
+
# end
|
367
|
+
#
|
368
|
+
# == Options
|
369
|
+
#
|
370
|
+
# Collection radio accepts some extra options:
|
371
|
+
#
|
372
|
+
# * checked => the value that should be checked initially.
|
373
|
+
#
|
374
|
+
# * disabled => the value or values that should be disabled. Accepts a single
|
375
|
+
# item or an array of items.
|
376
|
+
#
|
377
|
+
# * collection_wrapper_tag => the tag to wrap the entire collection.
|
378
|
+
#
|
379
|
+
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag
|
380
|
+
#
|
381
|
+
# * item_wrapper_tag => the tag to wrap each item in the collection.
|
382
|
+
#
|
383
|
+
# * item_wrapper_class => the CSS class to use for item_wrapper_tag
|
384
|
+
#
|
385
|
+
# * a block => to generate the label + radio or any other component.
|
386
|
+
def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
387
|
+
SimpleForm::Tags::CollectionRadioButtons.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
|
388
|
+
end
|
389
|
+
|
390
|
+
# Creates a collection of check boxes for each item in the collection,
|
391
|
+
# associated with a clickable label. Use value_method and text_method to
|
392
|
+
# convert items in the collection for use as text/value in check boxes.
|
393
|
+
# You can give a symbol or a proc to both value_method and text_method,
|
394
|
+
# that will be evaluated for each item in the collection.
|
395
|
+
#
|
396
|
+
# == Examples
|
397
|
+
#
|
398
|
+
# form_for @user do |f|
|
399
|
+
# f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
400
|
+
# end
|
401
|
+
#
|
402
|
+
# <input name="user[options][]" type="hidden" value="" />
|
403
|
+
# <input id="user_options_true" name="user[options][]" type="checkbox" value="true" />
|
404
|
+
# <label class="collection_check_boxes" for="user_options_true">Yes</label>
|
405
|
+
# <input name="user[options][]" type="hidden" value="" />
|
406
|
+
# <input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
|
407
|
+
# <label class="collection_check_boxes" for="user_options_false">No</label>
|
408
|
+
#
|
409
|
+
# It is also possible to give a block that should generate the check box +
|
410
|
+
# label. To wrap the check box with the label, for instance:
|
411
|
+
#
|
412
|
+
# form_for @user do |f|
|
413
|
+
# f.collection_check_boxes(
|
414
|
+
# :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
|
415
|
+
# ) do |b|
|
416
|
+
# b.label { b.check_box + b.text }
|
417
|
+
# end
|
418
|
+
# end
|
419
|
+
#
|
420
|
+
# == Options
|
421
|
+
#
|
422
|
+
# Collection check box accepts some extra options:
|
423
|
+
#
|
424
|
+
# * checked => the value or values that should be checked initially. Accepts
|
425
|
+
# a single item or an array of items. It overrides existing associations.
|
426
|
+
#
|
427
|
+
# * disabled => the value or values that should be disabled. Accepts a single
|
428
|
+
# item or an array of items.
|
429
|
+
#
|
430
|
+
# * collection_wrapper_tag => the tag to wrap the entire collection.
|
431
|
+
#
|
432
|
+
# * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option
|
433
|
+
# is ignored if the :collection_wrapper_tag option is blank.
|
434
|
+
#
|
435
|
+
# * item_wrapper_tag => the tag to wrap each item in the collection.
|
436
|
+
#
|
437
|
+
# * item_wrapper_class => the CSS class to use for item_wrapper_tag
|
438
|
+
#
|
439
|
+
# * a block => to generate the label + check box or any other component.
|
440
|
+
def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
441
|
+
SimpleForm::Tags::CollectionCheckBoxes.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
|
442
|
+
end
|
443
|
+
|
334
444
|
# Extract the model names from the object_name mess, ignoring numeric and
|
335
445
|
# explicit child indexes.
|
336
446
|
#
|
@@ -339,10 +449,10 @@ module SimpleForm
|
|
339
449
|
# route[blocks_attributes][0][blocks_learning_object_attributes][1][foo_attributes]
|
340
450
|
# ["route", "blocks", "blocks_learning_object", "foo"]
|
341
451
|
#
|
342
|
-
def lookup_model_names
|
452
|
+
def lookup_model_names #:nodoc:
|
343
453
|
@lookup_model_names ||= begin
|
344
454
|
child_index = options[:child_index]
|
345
|
-
names = object_name.to_s.scan(/(
|
455
|
+
names = object_name.to_s.scan(/(?!\d)\w+/).flatten
|
346
456
|
names.delete(child_index) if child_index
|
347
457
|
names.each { |name| name.gsub!('_attributes', '') }
|
348
458
|
names.freeze
|
@@ -350,9 +460,9 @@ module SimpleForm
|
|
350
460
|
end
|
351
461
|
|
352
462
|
# The action to be used in lookup.
|
353
|
-
def lookup_action
|
463
|
+
def lookup_action #:nodoc:
|
354
464
|
@lookup_action ||= begin
|
355
|
-
action = template.controller.action_name
|
465
|
+
action = template.controller && template.controller.action_name
|
356
466
|
return unless action
|
357
467
|
action = action.to_sym
|
358
468
|
ACTIONS[action] || action
|
@@ -366,12 +476,6 @@ module SimpleForm
|
|
366
476
|
column = find_attribute_column(attribute_name)
|
367
477
|
input_type = default_input_type(attribute_name, column, options)
|
368
478
|
|
369
|
-
if input_type == :radio
|
370
|
-
SimpleForm.deprecation_warn "Using `:as => :radio` as input type is " \
|
371
|
-
"deprecated, please change it to `:as => :radio_buttons`."
|
372
|
-
input_type = :radio_buttons
|
373
|
-
end
|
374
|
-
|
375
479
|
if block_given?
|
376
480
|
SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block)
|
377
481
|
else
|
data/lib/simple_form/helpers.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module SimpleForm
|
2
2
|
# Helpers are made of several helpers that cannot be turned on automatically.
|
3
3
|
# For instance, disabled cannot be turned on automatically, it requires the
|
4
|
-
# user to explicitly pass the option :
|
4
|
+
# user to explicitly pass the option disabled: true so it may work.
|
5
5
|
module Helpers
|
6
6
|
autoload :Autofocus, 'simple_form/helpers/autofocus'
|
7
7
|
autoload :Disabled, 'simple_form/helpers/disabled'
|
@@ -24,7 +24,7 @@ module SimpleForm
|
|
24
24
|
attr_reader :attribute_name, :column, :input_type, :reflection,
|
25
25
|
:options, :input_html_options, :input_html_classes, :html_classes
|
26
26
|
|
27
|
-
delegate :template, :object, :object_name, :lookup_model_names, :lookup_action, :
|
27
|
+
delegate :template, :object, :object_name, :lookup_model_names, :lookup_action, to: :@builder
|
28
28
|
|
29
29
|
class_attribute :default_options
|
30
30
|
self.default_options = {}
|
@@ -65,6 +65,10 @@ module SimpleForm
|
|
65
65
|
@html_classes = SimpleForm.additional_classes_for(:input) { additional_classes }
|
66
66
|
|
67
67
|
@input_html_classes = @html_classes.dup
|
68
|
+
if SimpleForm.input_class && !input_html_classes.empty?
|
69
|
+
input_html_classes << SimpleForm.input_class
|
70
|
+
end
|
71
|
+
|
68
72
|
@input_html_options = html_options_for(:input, input_html_classes).tap do |o|
|
69
73
|
o[:readonly] = true if has_readonly?
|
70
74
|
o[:disabled] = true if has_disabled?
|
@@ -90,10 +94,6 @@ module SimpleForm
|
|
90
94
|
|
91
95
|
private
|
92
96
|
|
93
|
-
def add_size!
|
94
|
-
input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
|
95
|
-
end
|
96
|
-
|
97
97
|
def limit
|
98
98
|
if column
|
99
99
|
decimal_or_float? ? decimal_limit : column_limit
|
@@ -179,7 +179,7 @@ module SimpleForm
|
|
179
179
|
lookups << :"defaults.#{reflection_or_attribute_name}"
|
180
180
|
lookups << default
|
181
181
|
|
182
|
-
I18n.t(lookups.shift, :
|
182
|
+
I18n.t(lookups.shift, scope: :"simple_form.#{namespace}", default: lookups).presence
|
183
183
|
end
|
184
184
|
end
|
185
185
|
end
|
@@ -4,7 +4,7 @@ module SimpleForm
|
|
4
4
|
def input
|
5
5
|
if nested_boolean_style?
|
6
6
|
build_hidden_field_for_checkbox +
|
7
|
-
template.label_tag(nil, :
|
7
|
+
template.label_tag(nil, class: "checkbox") {
|
8
8
|
build_check_box_without_hidden_field + inline_label
|
9
9
|
}
|
10
10
|
else
|
@@ -17,6 +17,7 @@ module SimpleForm
|
|
17
17
|
input
|
18
18
|
elsif nested_boolean_style?
|
19
19
|
html_options = label_html_options.dup
|
20
|
+
html_options[:class] ||= []
|
20
21
|
html_options[:class].push(:checkbox)
|
21
22
|
|
22
23
|
build_hidden_field_for_checkbox +
|
@@ -49,9 +50,10 @@ module SimpleForm
|
|
49
50
|
# we need the hidden field to be *outside* the label (otherwise it
|
50
51
|
# generates invalid html - html5 only).
|
51
52
|
def build_hidden_field_for_checkbox
|
52
|
-
|
53
|
-
|
54
|
-
|
53
|
+
options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
|
54
|
+
options[:name] = input_html_options[:name] if input_html_options.has_key?(:name)
|
55
|
+
|
56
|
+
@builder.hidden_field(attribute_name, options)
|
55
57
|
end
|
56
58
|
|
57
59
|
def inline_label
|
@@ -7,8 +7,8 @@ module SimpleForm
|
|
7
7
|
# "simple_form.no" keys. See the example locale file.
|
8
8
|
def self.boolean_collection
|
9
9
|
i18n_cache :boolean_collection do
|
10
|
-
[ [I18n.t(:"simple_form.yes", :
|
11
|
-
[I18n.t(:"simple_form.no", :
|
10
|
+
[ [I18n.t(:"simple_form.yes", default: 'Yes'), true],
|
11
|
+
[I18n.t(:"simple_form.no", default: 'No'), false] ]
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -66,14 +66,14 @@ module SimpleForm
|
|
66
66
|
collection_translated = translate_collection if collection_classes == [Symbol]
|
67
67
|
|
68
68
|
if collection_translated || collection_classes.include?(Array)
|
69
|
-
{ :
|
69
|
+
{ label: :first, value: :second }
|
70
70
|
elsif collection_includes_basic_objects?(collection_classes)
|
71
|
-
{ :
|
71
|
+
{ label: :to_s, value: :to_s }
|
72
72
|
else
|
73
73
|
sample = collection.first || collection.last
|
74
74
|
|
75
|
-
{ :
|
76
|
-
:
|
75
|
+
{ label: SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
|
76
|
+
value: SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -4,7 +4,6 @@ module SimpleForm
|
|
4
4
|
enable :placeholder, :min_max
|
5
5
|
|
6
6
|
def input
|
7
|
-
add_size!
|
8
7
|
input_html_classes.unshift("numeric")
|
9
8
|
if html5?
|
10
9
|
input_html_options[:type] ||= "number"
|
@@ -14,11 +13,6 @@ module SimpleForm
|
|
14
13
|
end
|
15
14
|
|
16
15
|
private
|
17
|
-
|
18
|
-
# Rails adds the size attr by default, if the :size key does not exist.
|
19
|
-
def add_size!
|
20
|
-
input_html_options[:size] ||= nil
|
21
|
-
end
|
22
16
|
end
|
23
17
|
end
|
24
18
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module SimpleForm
|
2
|
+
module Tags
|
3
|
+
module CollectionExtensions
|
4
|
+
private
|
5
|
+
|
6
|
+
def render_collection
|
7
|
+
item_wrapper_tag = @options.fetch(:item_wrapper_tag, :span)
|
8
|
+
item_wrapper_class = @options[:item_wrapper_class]
|
9
|
+
|
10
|
+
@collection.map do |item|
|
11
|
+
value = value_for_collection(item, @value_method)
|
12
|
+
text = value_for_collection(item, @text_method)
|
13
|
+
default_html_options = default_html_options_for_collection(item, value)
|
14
|
+
additional_html_options = option_html_attributes(item)
|
15
|
+
|
16
|
+
rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)
|
17
|
+
|
18
|
+
item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item
|
19
|
+
end.join.html_safe
|
20
|
+
end
|
21
|
+
|
22
|
+
def wrap_rendered_collection(collection)
|
23
|
+
wrapper_tag = @options[:collection_wrapper_tag]
|
24
|
+
|
25
|
+
if wrapper_tag
|
26
|
+
wrapper_class = @options[:collection_wrapper_class]
|
27
|
+
@template_object.content_tag(wrapper_tag, collection, class: wrapper_class)
|
28
|
+
else
|
29
|
+
collection
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class CollectionRadioButtons < ActionView::Helpers::Tags::CollectionRadioButtons
|
35
|
+
include CollectionExtensions
|
36
|
+
|
37
|
+
def render
|
38
|
+
wrap_rendered_collection(super)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def render_component(builder)
|
44
|
+
builder.radio_button + builder.label(class: "collection_radio_buttons")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCheckBoxes
|
49
|
+
include CollectionExtensions
|
50
|
+
|
51
|
+
def render
|
52
|
+
wrap_rendered_collection(super)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def render_component(builder)
|
58
|
+
builder.check_box + builder.label(class: "collection_check_boxes")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/simple_form/version.rb
CHANGED