simple_form 2.1.3 → 3.0.0.rc

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -50
  3. data/README.md +140 -116
  4. data/lib/generators/simple_form/install_generator.rb +4 -4
  5. data/lib/generators/simple_form/templates/README +2 -2
  6. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +13 -13
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +16 -16
  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 -320
  10. data/lib/simple_form/action_view_extensions/form_helper.rb +2 -9
  11. data/lib/simple_form/components/errors.rb +1 -7
  12. data/lib/simple_form/components/hints.rb +2 -7
  13. data/lib/simple_form/components/html5.rb +5 -2
  14. data/lib/simple_form/components/labels.rb +4 -4
  15. data/lib/simple_form/components/maxlength.rb +1 -8
  16. data/lib/simple_form/components/pattern.rb +2 -2
  17. data/lib/simple_form/components.rb +1 -1
  18. data/lib/simple_form/error_notification.rb +2 -2
  19. data/lib/simple_form/form_builder.rb +148 -50
  20. data/lib/simple_form/helpers.rb +1 -1
  21. data/lib/simple_form/inputs/base.rb +3 -10
  22. data/lib/simple_form/inputs/block_input.rb +1 -1
  23. data/lib/simple_form/inputs/boolean_input.rb +6 -6
  24. data/lib/simple_form/inputs/collection_input.rb +7 -7
  25. data/lib/simple_form/inputs/numeric_input.rb +0 -6
  26. data/lib/simple_form/inputs/password_input.rb +0 -1
  27. data/lib/simple_form/inputs/string_input.rb +0 -1
  28. data/lib/simple_form/railtie.rb +7 -0
  29. data/lib/simple_form/tags.rb +61 -0
  30. data/lib/simple_form/version.rb +1 -1
  31. data/lib/simple_form/wrappers/builder.rb +5 -29
  32. data/lib/simple_form/wrappers/many.rb +1 -1
  33. data/lib/simple_form/wrappers/root.rb +1 -1
  34. data/lib/simple_form/wrappers.rb +1 -1
  35. data/lib/simple_form.rb +39 -47
  36. data/test/action_view_extensions/builder_test.rb +75 -95
  37. data/test/action_view_extensions/form_helper_test.rb +25 -16
  38. data/test/components/label_test.rb +46 -46
  39. data/test/form_builder/association_test.rb +39 -29
  40. data/test/form_builder/button_test.rb +4 -4
  41. data/test/form_builder/error_notification_test.rb +8 -8
  42. data/test/form_builder/error_test.rb +18 -65
  43. data/test/form_builder/general_test.rb +60 -74
  44. data/test/form_builder/hint_test.rb +23 -29
  45. data/test/form_builder/input_field_test.rb +12 -12
  46. data/test/form_builder/label_test.rb +6 -16
  47. data/test/form_builder/wrapper_test.rb +21 -21
  48. data/test/inputs/boolean_input_test.rb +23 -35
  49. data/test/inputs/collection_check_boxes_input_test.rb +61 -55
  50. data/test/inputs/collection_radio_buttons_input_test.rb +76 -79
  51. data/test/inputs/collection_select_input_test.rb +70 -51
  52. data/test/inputs/datetime_input_test.rb +17 -11
  53. data/test/inputs/disabled_test.rb +10 -10
  54. data/test/inputs/discovery_test.rb +4 -4
  55. data/test/inputs/file_input_test.rb +1 -1
  56. data/test/inputs/general_test.rb +12 -12
  57. data/test/inputs/grouped_collection_select_input_test.rb +20 -20
  58. data/test/inputs/hidden_input_test.rb +3 -2
  59. data/test/inputs/numeric_input_test.rb +3 -3
  60. data/test/inputs/priority_input_test.rb +9 -3
  61. data/test/inputs/readonly_test.rb +12 -12
  62. data/test/inputs/required_test.rb +5 -5
  63. data/test/inputs/string_input_test.rb +15 -25
  64. data/test/inputs/text_input_test.rb +1 -1
  65. data/test/support/misc_helpers.rb +46 -24
  66. data/test/support/mock_controller.rb +6 -6
  67. data/test/support/models.rb +62 -64
  68. data/test/test_helper.rb +20 -24
  69. metadata +37 -23
  70. data/lib/simple_form/core_ext/hash.rb +0 -16
@@ -13,8 +13,8 @@ module SimpleForm
13
13
  pattern = options[:pattern]
14
14
  if pattern.is_a?(String)
15
15
  pattern
16
- elsif pattern_validator = find_pattern_validator
17
- evaluate_format_validator_option(pattern_validator.options[:with]).source
16
+ elsif (pattern_validator = find_pattern_validator) && (with = pattern_validator.options[:with])
17
+ evaluate_format_validator_option(with).source
18
18
  end
19
19
  end
20
20
 
@@ -2,7 +2,7 @@ module SimpleForm
2
2
  # Components are a special type of helpers that can work on their own.
3
3
  # For example, by using a component, it will automatically change the
4
4
  # output under given circumstances without user input. For example,
5
- # the disabled helper always need a :disabled => true option given
5
+ # the disabled helper always need a disabled: true option given
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
@@ -1,6 +1,6 @@
1
1
  module SimpleForm
2
2
  class ErrorNotification
3
- delegate :object, :object_name, :template, :to => :@builder
3
+ delegate :object, :object_name, :template, to: :@builder
4
4
 
5
5
  def initialize(builder, options)
6
6
  @builder = builder
@@ -42,7 +42,7 @@ module SimpleForm
42
42
  lookups << :"#{object_name}"
43
43
  lookups << :default_message
44
44
  lookups << "Please review the problems below:"
45
- I18n.t(lookups.shift, :scope => :"simple_form.error_notification", :default => lookups)
45
+ I18n.t(lookups.shift, scope: :"simple_form.error_notification", default: lookups)
46
46
  end
47
47
  end
48
48
  end
@@ -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,26 @@ 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
 
14
15
  extend MapType
15
16
  include SimpleForm::Inputs
16
17
 
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
18
+ map_type :text, to: SimpleForm::Inputs::TextInput
19
+ map_type :file, to: SimpleForm::Inputs::FileInput
20
+ map_type :string, :email, :search, :tel, :url, to: SimpleForm::Inputs::StringInput
21
+ map_type :password, to: SimpleForm::Inputs::PasswordInput
22
+ map_type :integer, :decimal, :float, to: SimpleForm::Inputs::NumericInput
23
+ map_type :range, to: SimpleForm::Inputs::RangeInput
24
+ map_type :check_boxes, to: SimpleForm::Inputs::CollectionCheckBoxesInput
25
+ map_type :radio_buttons, to: SimpleForm::Inputs::CollectionRadioButtonsInput
26
+ map_type :select, to: SimpleForm::Inputs::CollectionSelectInput
27
+ map_type :grouped_select, to: SimpleForm::Inputs::GroupedCollectionSelectInput
28
+ map_type :date, :time, :datetime, to: SimpleForm::Inputs::DateTimeInput
29
+ map_type :country, :time_zone, to: SimpleForm::Inputs::PriorityInput
30
+ map_type :boolean, to: SimpleForm::Inputs::BooleanInput
30
31
 
31
32
  def self.discovery_cache
32
33
  @discovery_cache ||= {}
@@ -48,7 +49,7 @@ module SimpleForm
48
49
  #
49
50
  # # Imagine @user has error "can't be blank" on name
50
51
  # simple_form_for @user do |f|
51
- # f.input :name, :hint => 'My hint'
52
+ # f.input :name, hint: 'My hint'
52
53
  # end
53
54
  #
54
55
  # This is the output html (only the input portion, not the form):
@@ -57,7 +58,7 @@ module SimpleForm
57
58
  # <abbr title="required">*</abbr> Super User Name!
58
59
  # </label>
59
60
  # <input class="string required" id="user_name" maxlength="100"
60
- # name="user[name]" size="100" type="text" value="Carlos" />
61
+ # name="user[name]" type="text" value="Carlos" />
61
62
  # <span class="hint">My hint</span>
62
63
  # <span class="error">can't be blank</span>
63
64
  #
@@ -66,15 +67,15 @@ module SimpleForm
66
67
  #
67
68
  # You have some options for the input to enable/disable some functions:
68
69
  #
69
- # :as => allows you to define the input type you want, for instance you
70
+ # as: allows you to define the input type you want, for instance you
70
71
  # can use it to generate a text field for a date column.
71
72
  #
72
- # :required => defines whether this attribute is required or not. True
73
+ # required: defines whether this attribute is required or not. True
73
74
  # by default.
74
75
  #
75
76
  # The fact SimpleForm is built in components allow the interface to be unified.
76
77
  # 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.
78
+ # hint: false. The same works for :error, :label and :wrapper.
78
79
  #
79
80
  # Besides the html for any component can be changed. So, if you want to change
80
81
  # the label html you just need to give a hash to :label_html. To configure the
@@ -85,18 +86,18 @@ module SimpleForm
85
86
  # Some inputs, as datetime, time and select allow you to give extra options, like
86
87
  # prompt and/or include blank. Such options are given in plainly:
87
88
  #
88
- # f.input :created_at, :include_blank => true
89
+ # f.input :created_at, include_blank: true
89
90
  #
90
91
  # == Collection
91
92
  #
92
93
  # When playing with collections (:radio_buttons, :check_boxes and :select
93
94
  # inputs), you have three extra options:
94
95
  #
95
- # :collection => use to determine the collection to generate the radio or select
96
+ # collection: use to determine the collection to generate the radio or select
96
97
  #
97
- # :label_method => the method to apply on the array collection to get the label
98
+ # label_method: the method to apply on the array collection to get the label
98
99
  #
99
- # :value_method => the method to apply on the array collection to get the value
100
+ # value_method: the method to apply on the array collection to get the value
100
101
  #
101
102
  # == Priority
102
103
  #
@@ -130,14 +131,14 @@ module SimpleForm
130
131
  # This is the output html (only the input portion, not the form):
131
132
  #
132
133
  # <input class="string required" id="user_name" maxlength="100"
133
- # name="user[name]" size="100" type="text" value="Carlos" />
134
+ # name="user[name]" type="text" value="Carlos" />
134
135
  #
135
136
  def input_field(attribute_name, options={})
136
137
  options = options.dup
137
138
  options[:input_html] = options.except(:as, :collection, :label_method, :value_method)
138
139
  options = @defaults.deep_dup.deep_merge(options) if @defaults
139
140
 
140
- SimpleForm::Wrappers::Root.new([:min_max, :maxlength, :placeholder, :pattern, :readonly, :input], :wrapper => false).render find_input(attribute_name, options)
141
+ SimpleForm::Wrappers::Root.new([:min_max, :maxlength, :placeholder, :pattern, :readonly, :input], wrapper: false).render find_input(attribute_name, options)
141
142
  end
142
143
 
143
144
  # Helper for dealing with association selects/radios, generating the
@@ -151,7 +152,7 @@ module SimpleForm
151
152
  # f.association :company # Company.all
152
153
  # end
153
154
  #
154
- # f.association :company, :collection => Company.all(:order => 'name')
155
+ # f.association :company, collection: Company.all(order: 'name')
155
156
  # # Same as using :order option, but overriding collection
156
157
  #
157
158
  # == Block
@@ -179,7 +180,7 @@ module SimpleForm
179
180
 
180
181
  options[:as] ||= :select
181
182
  options[:collection] ||= options.fetch(:collection) {
182
- reflection.klass.all(reflection.options.slice(:conditions, :order))
183
+ reflection.klass.where(reflection.options[:conditions]).order(reflection.options[:order]).to_a
183
184
  }
184
185
 
185
186
  attribute = case reflection.macro
@@ -190,7 +191,6 @@ module SimpleForm
190
191
  else
191
192
  if options[:as] == :select
192
193
  html_options = options[:input_html] ||= {}
193
- html_options[:size] ||= 5
194
194
  html_options[:multiple] = true unless html_options.key?(:multiple)
195
195
  end
196
196
 
@@ -203,7 +203,7 @@ module SimpleForm
203
203
  :"#{reflection.name.to_s.singularize}_ids"
204
204
  end
205
205
 
206
- input(attribute, options.merge(:reflection => reflection))
206
+ input(attribute, options.merge(reflection: reflection))
207
207
  end
208
208
 
209
209
  # Creates a button:
@@ -216,8 +216,7 @@ module SimpleForm
216
216
  # button implementation (3.2 forward (to delegate to the original when
217
217
  # calling `f.button :button`.
218
218
  #
219
- # TODO: remove if condition when supporting only Rails 3.2 forward.
220
- alias_method :button_button, :button if method_defined?(:button)
219
+ alias_method :button_button, :button
221
220
  def button(type, *args, &block)
222
221
  options = args.extract_options!.dup
223
222
  options[:class] = [SimpleForm.button_class, options[:class]].compact
@@ -235,7 +234,7 @@ module SimpleForm
235
234
  # == Examples
236
235
  #
237
236
  # f.error :name
238
- # f.error :name, :id => "cool_error"
237
+ # f.error :name, id: "cool_error"
239
238
  #
240
239
  def error(attribute_name, options={})
241
240
  options = options.dup
@@ -273,7 +272,7 @@ module SimpleForm
273
272
  # == Examples
274
273
  #
275
274
  # f.hint :name # Do I18n lookup
276
- # f.hint :name, :id => "cool_hint"
275
+ # f.hint :name, id: "cool_hint"
277
276
  # f.hint "Don't forget to accept this"
278
277
  #
279
278
  def hint(attribute_name, options={})
@@ -300,10 +299,10 @@ module SimpleForm
300
299
  #
301
300
  # f.label :name # Do I18n lookup
302
301
  # 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
302
+ # f.label :name, label: "Name" # Same as above, but adds required tag
304
303
  #
305
- # f.label :name, :required => false
306
- # f.label :name, :id => "cool_label"
304
+ # f.label :name, required: false
305
+ # f.label :name, id: "cool_label"
307
306
  #
308
307
  def label(attribute_name, *args)
309
308
  return super if args.first.is_a?(String) || block_given?
@@ -324,13 +323,118 @@ module SimpleForm
324
323
  # == Examples
325
324
  #
326
325
  # f.error_notification
327
- # f.error_notification :message => 'Something went wrong'
328
- # f.error_notification :id => 'user_error_message', :class => 'form_error'
326
+ # f.error_notification message: 'Something went wrong'
327
+ # f.error_notification id: 'user_error_message', class: 'form_error'
329
328
  #
330
329
  def error_notification(options={})
331
330
  SimpleForm::ErrorNotification.new(self, options).render
332
331
  end
333
332
 
333
+ # Create a collection of radio inputs for the attribute. Basically this
334
+ # helper will create a radio input associated with a label for each
335
+ # text/value option in the collection, using value_method and text_method
336
+ # to convert these text/value. You can give a symbol or a proc to both
337
+ # value_method and text_method, that will be evaluated for each item in
338
+ # the collection.
339
+ #
340
+ # == Examples
341
+ #
342
+ # form_for @user do |f|
343
+ # f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
344
+ # end
345
+ #
346
+ # <input id="user_options_true" name="user[options]" type="radio" value="true" />
347
+ # <label class="collection_radio_buttons" for="user_options_true">Yes</label>
348
+ # <input id="user_options_false" name="user[options]" type="radio" value="false" />
349
+ # <label class="collection_radio_buttons" for="user_options_false">No</label>
350
+ #
351
+ # It is also possible to give a block that should generate the radio +
352
+ # label. To wrap the radio with the label, for instance:
353
+ #
354
+ # form_for @user do |f|
355
+ # f.collection_radio_buttons(
356
+ # :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
357
+ # ) do |b|
358
+ # b.label { b.radio_button + b.text }
359
+ # end
360
+ # end
361
+ #
362
+ # == Options
363
+ #
364
+ # Collection radio accepts some extra options:
365
+ #
366
+ # * checked => the value that should be checked initially.
367
+ #
368
+ # * disabled => the value or values that should be disabled. Accepts a single
369
+ # item or an array of items.
370
+ #
371
+ # * collection_wrapper_tag => the tag to wrap the entire collection.
372
+ #
373
+ # * collection_wrapper_class => the CSS class to use for collection_wrapper_tag
374
+ #
375
+ # * item_wrapper_tag => the tag to wrap each item in the collection.
376
+ #
377
+ # * item_wrapper_class => the CSS class to use for item_wrapper_tag
378
+ #
379
+ # * a block => to generate the label + radio or any other component.
380
+ def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
381
+ SimpleForm::Tags::CollectionRadioButtons.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
382
+ end
383
+
384
+ # Creates a collection of check boxes for each item in the collection,
385
+ # associated with a clickable label. Use value_method and text_method to
386
+ # convert items in the collection for use as text/value in check boxes.
387
+ # You can give a symbol or a proc to both value_method and text_method,
388
+ # that will be evaluated for each item in the collection.
389
+ #
390
+ # == Examples
391
+ #
392
+ # form_for @user do |f|
393
+ # f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
394
+ # end
395
+ #
396
+ # <input name="user[options][]" type="hidden" value="" />
397
+ # <input id="user_options_true" name="user[options][]" type="checkbox" value="true" />
398
+ # <label class="collection_check_boxes" for="user_options_true">Yes</label>
399
+ # <input name="user[options][]" type="hidden" value="" />
400
+ # <input id="user_options_false" name="user[options][]" type="checkbox" value="false" />
401
+ # <label class="collection_check_boxes" for="user_options_false">No</label>
402
+ #
403
+ # It is also possible to give a block that should generate the check box +
404
+ # label. To wrap the check box with the label, for instance:
405
+ #
406
+ # form_for @user do |f|
407
+ # f.collection_check_boxes(
408
+ # :options, [[true, 'Yes'] ,[false, 'No']], :first, :last
409
+ # ) do |b|
410
+ # b.label { b.check_box + b.text }
411
+ # end
412
+ # end
413
+ #
414
+ # == Options
415
+ #
416
+ # Collection check box accepts some extra options:
417
+ #
418
+ # * checked => the value or values that should be checked initially. Accepts
419
+ # a single item or an array of items. It overrides existing associations.
420
+ #
421
+ # * disabled => the value or values that should be disabled. Accepts a single
422
+ # item or an array of items.
423
+ #
424
+ # * collection_wrapper_tag => the tag to wrap the entire collection.
425
+ #
426
+ # * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option
427
+ # is ignored if the :collection_wrapper_tag option is blank.
428
+ #
429
+ # * item_wrapper_tag => the tag to wrap each item in the collection.
430
+ #
431
+ # * item_wrapper_class => the CSS class to use for item_wrapper_tag
432
+ #
433
+ # * a block => to generate the label + check box or any other component.
434
+ def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
435
+ SimpleForm::Tags::CollectionCheckBoxes.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)
436
+ end
437
+
334
438
  # Extract the model names from the object_name mess, ignoring numeric and
335
439
  # explicit child indexes.
336
440
  #
@@ -339,10 +443,10 @@ module SimpleForm
339
443
  # route[blocks_attributes][0][blocks_learning_object_attributes][1][foo_attributes]
340
444
  # ["route", "blocks", "blocks_learning_object", "foo"]
341
445
  #
342
- def lookup_model_names
446
+ def lookup_model_names #:nodoc:
343
447
  @lookup_model_names ||= begin
344
448
  child_index = options[:child_index]
345
- names = object_name.to_s.scan(/(?!\d)\w+/).flatten
449
+ names = object_name.to_s.scan(/([a-zA-Z_]+)/).flatten
346
450
  names.delete(child_index) if child_index
347
451
  names.each { |name| name.gsub!('_attributes', '') }
348
452
  names.freeze
@@ -350,9 +454,9 @@ module SimpleForm
350
454
  end
351
455
 
352
456
  # The action to be used in lookup.
353
- def lookup_action
457
+ def lookup_action #:nodoc:
354
458
  @lookup_action ||= begin
355
- action = template.controller.action_name
459
+ action = template.controller && template.controller.action_name
356
460
  return unless action
357
461
  action = action.to_sym
358
462
  ACTIONS[action] || action
@@ -366,12 +470,6 @@ module SimpleForm
366
470
  column = find_attribute_column(attribute_name)
367
471
  input_type = default_input_type(attribute_name, column, options)
368
472
 
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
473
  if block_given?
376
474
  SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block)
377
475
  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'
@@ -1,11 +1,8 @@
1
1
  require 'simple_form/i18n_cache'
2
- require 'active_support/core_ext/string/output_safety'
3
2
 
4
3
  module SimpleForm
5
4
  module Inputs
6
5
  class Base
7
- include ERB::Util
8
-
9
6
  extend I18nCache
10
7
 
11
8
  include SimpleForm::Helpers::Autofocus
@@ -27,7 +24,7 @@ module SimpleForm
27
24
  attr_reader :attribute_name, :column, :input_type, :reflection,
28
25
  :options, :input_html_options, :input_html_classes, :html_classes
29
26
 
30
- 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
31
28
 
32
29
  class_attribute :default_options
33
30
  self.default_options = {}
@@ -45,7 +42,7 @@ module SimpleForm
45
42
  end
46
43
 
47
44
  # Always enabled.
48
- enable :hint, :error
45
+ enable :hint
49
46
 
50
47
  # Usually disabled, needs to be enabled explicitly passing true as option.
51
48
  disable :maxlength, :placeholder, :pattern, :min_max
@@ -93,10 +90,6 @@ module SimpleForm
93
90
 
94
91
  private
95
92
 
96
- def add_size!
97
- input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
98
- end
99
-
100
93
  def limit
101
94
  if column
102
95
  decimal_or_float? ? decimal_limit : column_limit
@@ -182,7 +175,7 @@ module SimpleForm
182
175
  lookups << :"defaults.#{reflection_or_attribute_name}"
183
176
  lookups << default
184
177
 
185
- I18n.t(lookups.shift, :scope => :"simple_form.#{namespace}", :default => lookups).presence
178
+ I18n.t(lookups.shift, scope: :"simple_form.#{namespace}", default: lookups).presence
186
179
  end
187
180
  end
188
181
  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,7 +17,6 @@ module SimpleForm
17
17
  input
18
18
  elsif nested_boolean_style?
19
19
  html_options = label_html_options.dup
20
- html_options[:class] ||= []
21
20
  html_options[:class].push(:checkbox)
22
21
 
23
22
  build_hidden_field_for_checkbox +
@@ -35,7 +34,7 @@ module SimpleForm
35
34
  # reuse the method for nested boolean style, but with no unchecked value,
36
35
  # which won't generate the hidden checkbox. This is the default functionality
37
36
  # in Rails > 3.2.1, and is backported in SimpleForm AV helpers.
38
- def build_check_box(unchecked_value = unchecked_value())
37
+ def build_check_box(unchecked_value = unchecked_value)
39
38
  @builder.check_box(attribute_name, input_html_options, checked_value, unchecked_value)
40
39
  end
41
40
 
@@ -50,9 +49,10 @@ module SimpleForm
50
49
  # we need the hidden field to be *outside* the label (otherwise it
51
50
  # generates invalid html - html5 only).
52
51
  def build_hidden_field_for_checkbox
53
- @builder.hidden_field(attribute_name, :value => unchecked_value, :id => nil,
54
- :disabled => input_html_options[:disabled],
55
- :name => input_html_options[:name])
52
+ options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
53
+ options[:name] = input_html_options[:name] if input_html_options.has_key?(:name)
54
+
55
+ @builder.hidden_field(attribute_name, options)
56
56
  end
57
57
 
58
58
  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
 
@@ -33,7 +33,7 @@ module SimpleForm
33
33
  end
34
34
 
35
35
  def has_required?
36
- super && (input_options[:include_blank] || input_options[:prompt] || multiple?)
36
+ super && (input_options[:include_blank] || multiple?)
37
37
  end
38
38
 
39
39
  # Check if :include_blank must be included by default.
@@ -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: :last }
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
 
@@ -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,61 @@
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
+
15
+ rendered_item = yield item, value, text, default_html_options
16
+
17
+ item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item
18
+ end.join.html_safe
19
+ end
20
+
21
+ def wrap_rendered_collection(collection)
22
+ wrapper_tag = @options[:collection_wrapper_tag]
23
+
24
+ if wrapper_tag
25
+ wrapper_class = @options[:collection_wrapper_class]
26
+ @template_object.content_tag(wrapper_tag, collection, class: wrapper_class)
27
+ else
28
+ collection
29
+ end
30
+ end
31
+ end
32
+
33
+ class CollectionRadioButtons < ActionView::Helpers::Tags::CollectionRadioButtons
34
+ include CollectionExtensions
35
+
36
+ def render
37
+ wrap_rendered_collection(super)
38
+ end
39
+
40
+ private
41
+
42
+ def render_component(builder)
43
+ builder.radio_button + builder.label(class: "collection_radio_buttons")
44
+ end
45
+ end
46
+
47
+ class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCheckBoxes
48
+ include CollectionExtensions
49
+
50
+ def render
51
+ wrap_rendered_collection(super)
52
+ end
53
+
54
+ private
55
+
56
+ def render_component(builder)
57
+ builder.check_box + builder.label(class: "collection_check_boxes")
58
+ end
59
+ end
60
+ end
61
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleForm
2
- VERSION = "2.1.3".freeze
2
+ VERSION = "3.0.0.rc".freeze
3
3
  end