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.

Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +22 -32
  3. data/README.md +161 -119
  4. data/lib/generators/simple_form/install_generator.rb +3 -3
  5. data/lib/generators/simple_form/templates/README +1 -1
  6. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +16 -13
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +14 -14
  8. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +3 -3
  9. data/lib/simple_form/action_view_extensions/builder.rb +1 -319
  10. data/lib/simple_form/action_view_extensions/form_helper.rb +2 -9
  11. data/lib/simple_form/components/html5.rb +5 -2
  12. data/lib/simple_form/components/labels.rb +3 -3
  13. data/lib/simple_form/components/maxlength.rb +1 -8
  14. data/lib/simple_form/components/pattern.rb +2 -2
  15. data/lib/simple_form/components.rb +1 -1
  16. data/lib/simple_form/error_notification.rb +2 -2
  17. data/lib/simple_form/form_builder.rb +155 -51
  18. data/lib/simple_form/helpers.rb +1 -1
  19. data/lib/simple_form/inputs/base.rb +6 -6
  20. data/lib/simple_form/inputs/block_input.rb +1 -1
  21. data/lib/simple_form/inputs/boolean_input.rb +6 -4
  22. data/lib/simple_form/inputs/collection_input.rb +6 -6
  23. data/lib/simple_form/inputs/date_time_input.rb +1 -1
  24. data/lib/simple_form/inputs/numeric_input.rb +0 -6
  25. data/lib/simple_form/inputs/password_input.rb +0 -1
  26. data/lib/simple_form/inputs/string_input.rb +0 -1
  27. data/lib/simple_form/railtie.rb +7 -0
  28. data/lib/simple_form/tags.rb +62 -0
  29. data/lib/simple_form/version.rb +1 -1
  30. data/lib/simple_form/wrappers/builder.rb +5 -29
  31. data/lib/simple_form/wrappers/many.rb +1 -1
  32. data/lib/simple_form/wrappers/root.rb +1 -1
  33. data/lib/simple_form/wrappers.rb +1 -1
  34. data/lib/simple_form.rb +43 -47
  35. data/test/action_view_extensions/builder_test.rb +78 -92
  36. data/test/action_view_extensions/form_helper_test.rb +25 -16
  37. data/test/components/label_test.rb +46 -46
  38. data/test/form_builder/association_test.rb +47 -29
  39. data/test/form_builder/button_test.rb +4 -4
  40. data/test/form_builder/error_notification_test.rb +8 -8
  41. data/test/form_builder/error_test.rb +12 -12
  42. data/test/form_builder/general_test.rb +71 -52
  43. data/test/form_builder/hint_test.rb +22 -22
  44. data/test/form_builder/input_field_test.rb +29 -12
  45. data/test/form_builder/label_test.rb +7 -7
  46. data/test/form_builder/wrapper_test.rb +21 -21
  47. data/test/inputs/boolean_input_test.rb +35 -23
  48. data/test/inputs/collection_check_boxes_input_test.rb +66 -55
  49. data/test/inputs/collection_radio_buttons_input_test.rb +81 -79
  50. data/test/inputs/collection_select_input_test.rb +76 -45
  51. data/test/inputs/datetime_input_test.rb +17 -11
  52. data/test/inputs/disabled_test.rb +10 -10
  53. data/test/inputs/discovery_test.rb +4 -4
  54. data/test/inputs/file_input_test.rb +1 -1
  55. data/test/inputs/general_test.rb +28 -12
  56. data/test/inputs/grouped_collection_select_input_test.rb +33 -20
  57. data/test/inputs/hidden_input_test.rb +3 -2
  58. data/test/inputs/numeric_input_test.rb +3 -3
  59. data/test/inputs/priority_input_test.rb +9 -3
  60. data/test/inputs/readonly_test.rb +12 -12
  61. data/test/inputs/required_test.rb +5 -5
  62. data/test/inputs/string_input_test.rb +15 -25
  63. data/test/inputs/text_input_test.rb +1 -1
  64. data/test/support/misc_helpers.rb +46 -24
  65. data/test/support/mock_controller.rb +6 -6
  66. data/test/support/models.rb +80 -62
  67. data/test/test_helper.rb +17 -34
  68. metadata +31 -29
  69. data/lib/simple_form/core_ext/hash.rb +0 -16
@@ -1,5 +1,6 @@
1
- require 'simple_form/core_ext/hash'
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
- :create => :new,
11
- :update => :edit
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, :to => SimpleForm::Inputs::TextInput
18
- map_type :file, :to => SimpleForm::Inputs::FileInput
19
- map_type :string, :email, :search, :tel, :url, :to => SimpleForm::Inputs::StringInput
20
- map_type :password, :to => SimpleForm::Inputs::PasswordInput
21
- map_type :integer, :decimal, :float, :to => SimpleForm::Inputs::NumericInput
22
- map_type :range, :to => SimpleForm::Inputs::RangeInput
23
- map_type :check_boxes, :to => SimpleForm::Inputs::CollectionCheckBoxesInput
24
- map_type :radio_buttons, :to => SimpleForm::Inputs::CollectionRadioButtonsInput
25
- map_type :select, :to => SimpleForm::Inputs::CollectionSelectInput
26
- map_type :grouped_select, :to => SimpleForm::Inputs::GroupedCollectionSelectInput
27
- map_type :date, :time, :datetime, :to => SimpleForm::Inputs::DateTimeInput
28
- map_type :country, :time_zone, :to => SimpleForm::Inputs::PriorityInput
29
- map_type :boolean, :to => SimpleForm::Inputs::BooleanInput
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, :hint => 'My hint'
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]" size="100" type="text" value="Carlos" />
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
- # :as => allows you to define the input type you want, for instance you
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
- # :required => defines whether this attribute is required or not. True
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
- # :hint => false. The same works for :error, :label and :wrapper.
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, :include_blank => true
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
- # :collection => use to determine the collection to generate the radio or select
98
+ # collection: use to determine the collection to generate the radio or select
96
99
  #
97
- # :label_method => the method to apply on the array collection to get the label
100
+ # label_method: the method to apply on the array collection to get the label
98
101
  #
99
- # :value_method => the method to apply on the array collection to get the value
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]" size="100" type="text" value="Carlos" />
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([:min_max, :maxlength, :placeholder, :pattern, :readonly, :input], :wrapper => false).render find_input(attribute_name, options)
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, :collection => Company.all(:order => 'name')
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.klass.all(reflection.options.slice(:conditions, :order))
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(:reflection => reflection))
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
- # TODO: remove if condition when supporting only Rails 3.2 forward.
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, :id => "cool_error"
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, :id => "cool_hint"
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, :label => "Name" # Same as above, but adds required tag
308
+ # f.label :name, label: "Name" # Same as above, but adds required tag
304
309
  #
305
- # f.label :name, :required => false
306
- # f.label :name, :id => "cool_label"
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 :message => 'Something went wrong'
328
- # f.error_notification :id => 'user_error_message', :class => 'form_error'
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(/([a-zA-Z_]+)/).flatten
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
@@ -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 :disabled => true so it may work.
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, :to => :@builder
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, :scope => :"simple_form.#{namespace}", :default => lookups).presence
182
+ I18n.t(lookups.shift, scope: :"simple_form.#{namespace}", default: lookups).presence
183
183
  end
184
184
  end
185
185
  end
@@ -11,4 +11,4 @@ module SimpleForm
11
11
  end
12
12
  end
13
13
  end
14
- end
14
+ 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, :class => "checkbox") {
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
- @builder.hidden_field(attribute_name, :value => unchecked_value, :id => nil,
53
- :disabled => input_html_options[:disabled],
54
- :name => input_html_options[:name])
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", :default => 'Yes'), true],
11
- [I18n.t(:"simple_form.no", :default => 'No'), false] ]
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
- { :label => :first, :value => :last }
69
+ { label: :first, value: :second }
70
70
  elsif collection_includes_basic_objects?(collection_classes)
71
- { :label => :to_s, :value => :to_s }
71
+ { label: :to_s, value: :to_s }
72
72
  else
73
73
  sample = collection.first || collection.last
74
74
 
75
- { :label => SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
76
- :value => SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
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
 
@@ -11,7 +11,7 @@ module SimpleForm
11
11
  position = case input_type
12
12
  when :date, :datetime
13
13
  date_order = input_options[:order] || I18n.t('date.order')
14
- date_order.first
14
+ date_order.first.to_sym
15
15
  else
16
16
  :hour
17
17
  end
@@ -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
@@ -4,7 +4,6 @@ module SimpleForm
4
4
  enable :placeholder, :maxlength
5
5
 
6
6
  def input
7
- add_size!
8
7
  @builder.password_field(attribute_name, input_html_options)
9
8
  end
10
9
  end
@@ -9,7 +9,6 @@ module SimpleForm
9
9
  input_html_options[:type] ||= input_type if html5?
10
10
  end
11
11
 
12
- add_size!
13
12
  @builder.text_field(attribute_name, input_html_options)
14
13
  end
15
14
 
@@ -0,0 +1,7 @@
1
+ require 'rails/railtie'
2
+
3
+ module SimpleForm
4
+ class Railtie < Rails::Railtie
5
+ config.eager_load_namespaces << SimpleForm
6
+ end
7
+ 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
@@ -1,3 +1,3 @@
1
1
  module SimpleForm
2
- VERSION = "2.1.0".freeze
2
+ VERSION = "3.0.0".freeze
3
3
  end