simple_form 2.1.3 → 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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -51
  3. data/README.md +195 -161
  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 +16 -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/builder.rb.orig +247 -0
  11. data/lib/simple_form/action_view_extensions/form_helper.rb +2 -9
  12. data/lib/simple_form/components/errors.rb +1 -7
  13. data/lib/simple_form/components/hints.rb +2 -7
  14. data/lib/simple_form/components/html5.rb +5 -2
  15. data/lib/simple_form/components/labels.rb +4 -4
  16. data/lib/simple_form/components/maxlength.rb +1 -8
  17. data/lib/simple_form/components/pattern.rb +2 -2
  18. data/lib/simple_form/components.rb +1 -1
  19. data/lib/simple_form/error_notification.rb +2 -2
  20. data/lib/simple_form/form_builder.rb +154 -50
  21. data/lib/simple_form/form_builder.rb.orig +486 -0
  22. data/lib/simple_form/helpers.rb +1 -1
  23. data/lib/simple_form/inputs/base.rb +7 -10
  24. data/lib/simple_form/inputs/block_input.rb +1 -1
  25. data/lib/simple_form/inputs/boolean_input.rb +6 -5
  26. data/lib/simple_form/inputs/collection_input.rb +7 -7
  27. data/lib/simple_form/inputs/date_time_input.rb +1 -1
  28. data/lib/simple_form/inputs/numeric_input.rb +0 -6
  29. data/lib/simple_form/inputs/password_input.rb +0 -1
  30. data/lib/simple_form/inputs/string_input.rb +0 -1
  31. data/lib/simple_form/railtie.rb +7 -0
  32. data/lib/simple_form/tags.rb +62 -0
  33. data/lib/simple_form/version.rb +1 -1
  34. data/lib/simple_form/version.rb.orig +7 -0
  35. data/lib/simple_form/wrappers/builder.rb +5 -29
  36. data/lib/simple_form/wrappers/many.rb +1 -1
  37. data/lib/simple_form/wrappers/root.rb +1 -1
  38. data/lib/simple_form/wrappers.rb +1 -1
  39. data/lib/simple_form.rb +43 -47
  40. data/test/action_view_extensions/builder_test.rb +78 -99
  41. data/test/action_view_extensions/form_helper_test.rb +25 -16
  42. data/test/components/label_test.rb +46 -46
  43. data/test/form_builder/association_test.rb +47 -29
  44. data/test/form_builder/button_test.rb +4 -4
  45. data/test/form_builder/error_notification_test.rb +8 -8
  46. data/test/form_builder/error_test.rb +18 -65
  47. data/test/form_builder/general_test.rb +62 -63
  48. data/test/form_builder/hint_test.rb +23 -29
  49. data/test/form_builder/input_field_test.rb +29 -12
  50. data/test/form_builder/label_test.rb +7 -17
  51. data/test/form_builder/wrapper_test.rb +21 -21
  52. data/test/inputs/boolean_input_test.rb +24 -24
  53. data/test/inputs/collection_check_boxes_input_test.rb +66 -55
  54. data/test/inputs/collection_radio_buttons_input_test.rb +81 -79
  55. data/test/inputs/collection_select_input_test.rb +76 -51
  56. data/test/inputs/datetime_input_test.rb +17 -11
  57. data/test/inputs/disabled_test.rb +10 -10
  58. data/test/inputs/discovery_test.rb +4 -4
  59. data/test/inputs/file_input_test.rb +1 -1
  60. data/test/inputs/general_test.rb +28 -12
  61. data/test/inputs/grouped_collection_select_input_test.rb +33 -20
  62. data/test/inputs/hidden_input_test.rb +3 -2
  63. data/test/inputs/numeric_input_test.rb +3 -3
  64. data/test/inputs/priority_input_test.rb +9 -3
  65. data/test/inputs/readonly_test.rb +12 -12
  66. data/test/inputs/required_test.rb +5 -5
  67. data/test/inputs/string_input_test.rb +15 -25
  68. data/test/inputs/text_input_test.rb +1 -1
  69. data/test/support/misc_helpers.rb +46 -24
  70. data/test/support/mock_controller.rb +6 -6
  71. data/test/support/models.rb +77 -62
  72. data/test/test_helper.rb +17 -34
  73. metadata +39 -22
  74. data/lib/simple_form/core_ext/hash.rb +0 -16
@@ -0,0 +1,486 @@
1
+ <<<<<<< HEAD
2
+ require 'simple_form/core_ext/hash'
3
+ =======
4
+ require 'active_support/core_ext/object/deep_dup'
5
+ require 'simple_form/map_type'
6
+ >>>>>>> beeac4d... These modules don't need to be autoloaded
7
+
8
+ module SimpleForm
9
+ class FormBuilder < ActionView::Helpers::FormBuilder
10
+ attr_reader :template, :object_name, :object, :wrapper
11
+
12
+ # When action is create or update, we still should use new and edit
13
+ ACTIONS = {
14
+ :create => :new,
15
+ :update => :edit
16
+ }
17
+
18
+ extend MapType
19
+ include SimpleForm::Inputs
20
+
21
+ map_type :text, :to => SimpleForm::Inputs::TextInput
22
+ map_type :file, :to => SimpleForm::Inputs::FileInput
23
+ map_type :string, :email, :search, :tel, :url, :to => SimpleForm::Inputs::StringInput
24
+ map_type :password, :to => SimpleForm::Inputs::PasswordInput
25
+ map_type :integer, :decimal, :float, :to => SimpleForm::Inputs::NumericInput
26
+ map_type :range, :to => SimpleForm::Inputs::RangeInput
27
+ map_type :check_boxes, :to => SimpleForm::Inputs::CollectionCheckBoxesInput
28
+ map_type :radio_buttons, :to => SimpleForm::Inputs::CollectionRadioButtonsInput
29
+ map_type :select, :to => SimpleForm::Inputs::CollectionSelectInput
30
+ map_type :grouped_select, :to => SimpleForm::Inputs::GroupedCollectionSelectInput
31
+ map_type :date, :time, :datetime, :to => SimpleForm::Inputs::DateTimeInput
32
+ map_type :country, :time_zone, :to => SimpleForm::Inputs::PriorityInput
33
+ map_type :boolean, :to => SimpleForm::Inputs::BooleanInput
34
+
35
+ def self.discovery_cache
36
+ @discovery_cache ||= {}
37
+ end
38
+
39
+ def initialize(*) #:nodoc:
40
+ super
41
+ @defaults = options[:defaults]
42
+ @wrapper = SimpleForm.wrapper(options[:wrapper] || SimpleForm.default_wrapper)
43
+ end
44
+
45
+ # Basic input helper, combines all components in the stack to generate
46
+ # input html based on options the user define and some guesses through
47
+ # database column information. By default a call to input will generate
48
+ # label + input + hint (when defined) + errors (when exists), and all can
49
+ # be configured inside a wrapper html.
50
+ #
51
+ # == Examples
52
+ #
53
+ # # Imagine @user has error "can't be blank" on name
54
+ # simple_form_for @user do |f|
55
+ # f.input :name, :hint => 'My hint'
56
+ # end
57
+ #
58
+ # This is the output html (only the input portion, not the form):
59
+ #
60
+ # <label class="string required" for="user_name">
61
+ # <abbr title="required">*</abbr> Super User Name!
62
+ # </label>
63
+ # <input class="string required" id="user_name" maxlength="100"
64
+ # name="user[name]" size="100" type="text" value="Carlos" />
65
+ # <span class="hint">My hint</span>
66
+ # <span class="error">can't be blank</span>
67
+ #
68
+ # Each database type will render a default input, based on some mappings and
69
+ # heuristic to determine which is the best option.
70
+ #
71
+ # You have some options for the input to enable/disable some functions:
72
+ #
73
+ # :as => allows you to define the input type you want, for instance you
74
+ # can use it to generate a text field for a date column.
75
+ #
76
+ # :required => defines whether this attribute is required or not. True
77
+ # by default.
78
+ #
79
+ # The fact SimpleForm is built in components allow the interface to be unified.
80
+ # So, for instance, if you need to disable :hint for a given input, you can pass
81
+ # :hint => false. The same works for :error, :label and :wrapper.
82
+ #
83
+ # Besides the html for any component can be changed. So, if you want to change
84
+ # the label html you just need to give a hash to :label_html. To configure the
85
+ # input html, supply :input_html instead and so on.
86
+ #
87
+ # == Options
88
+ #
89
+ # Some inputs, as datetime, time and select allow you to give extra options, like
90
+ # prompt and/or include blank. Such options are given in plainly:
91
+ #
92
+ # f.input :created_at, :include_blank => true
93
+ #
94
+ # == Collection
95
+ #
96
+ # When playing with collections (:radio_buttons, :check_boxes and :select
97
+ # inputs), you have three extra options:
98
+ #
99
+ # :collection => use to determine the collection to generate the radio or select
100
+ #
101
+ # :label_method => the method to apply on the array collection to get the label
102
+ #
103
+ # :value_method => the method to apply on the array collection to get the value
104
+ #
105
+ # == Priority
106
+ #
107
+ # Some inputs, as :time_zone and :country accepts a :priority option. If none is
108
+ # given SimpleForm.time_zone_priority and SimpleForm.country_priority are used respectively.
109
+ #
110
+ def input(attribute_name, options={}, &block)
111
+ options = @defaults.deep_dup.deep_merge(options) if @defaults
112
+ input = find_input(attribute_name, options, &block)
113
+
114
+ chosen =
115
+ if name = options[:wrapper] || find_wrapper_mapping(input.input_type)
116
+ name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
117
+ else
118
+ wrapper
119
+ end
120
+
121
+ chosen.render input
122
+ end
123
+ alias :attribute :input
124
+
125
+ # Creates a input tag for the given attribute. All the given options
126
+ # are sent as :input_html.
127
+ #
128
+ # == Examples
129
+ #
130
+ # simple_form_for @user do |f|
131
+ # f.input_field :name
132
+ # end
133
+ #
134
+ # This is the output html (only the input portion, not the form):
135
+ #
136
+ # <input class="string required" id="user_name" maxlength="100"
137
+ # name="user[name]" size="100" type="text" value="Carlos" />
138
+ #
139
+ def input_field(attribute_name, options={})
140
+ options = options.dup
141
+ options[:input_html] = options.except(:as, :collection, :label_method, :value_method)
142
+ options = @defaults.deep_dup.deep_merge(options) if @defaults
143
+
144
+ SimpleForm::Wrappers::Root.new([:input], :wrapper => false).render find_input(attribute_name, options)
145
+ end
146
+
147
+ # Helper for dealing with association selects/radios, generating the
148
+ # collection automatically. It's just a wrapper to input, so all options
149
+ # supported in input are also supported by association. Some extra options
150
+ # can also be given:
151
+ #
152
+ # == Examples
153
+ #
154
+ # simple_form_for @user do |f|
155
+ # f.association :company # Company.all
156
+ # end
157
+ #
158
+ # f.association :company, :collection => Company.all(:order => 'name')
159
+ # # Same as using :order option, but overriding collection
160
+ #
161
+ # == Block
162
+ #
163
+ # When a block is given, association simple behaves as a proxy to
164
+ # simple_fields_for:
165
+ #
166
+ # f.association :company do |c|
167
+ # c.input :name
168
+ # c.input :type
169
+ # end
170
+ #
171
+ # From the options above, only :collection can also be supplied.
172
+ #
173
+ def association(association, options={}, &block)
174
+ options = options.dup
175
+
176
+ return simple_fields_for(*[association,
177
+ options.delete(:collection), options].compact, &block) if block_given?
178
+
179
+ raise ArgumentError, "Association cannot be used in forms not associated with an object" unless @object
180
+
181
+ reflection = find_association_reflection(association)
182
+ raise "Association #{association.inspect} not found" unless reflection
183
+
184
+ options[:as] ||= :select
185
+ options[:collection] ||= options.fetch(:collection) {
186
+ reflection.klass.all(reflection.options.slice(:conditions, :order))
187
+ }
188
+
189
+ attribute = case reflection.macro
190
+ when :belongs_to
191
+ (reflection.respond_to?(:options) && reflection.options[:foreign_key]) || :"#{reflection.name}_id"
192
+ when :has_one
193
+ raise ArgumentError, ":has_one associations are not supported by f.association"
194
+ else
195
+ if options[:as] == :select
196
+ html_options = options[:input_html] ||= {}
197
+ html_options[:size] ||= 5
198
+ html_options[:multiple] = true unless html_options.key?(:multiple)
199
+ end
200
+
201
+ # Force the association to be preloaded for performance.
202
+ if options[:preload] != false && object.respond_to?(association)
203
+ target = object.send(association)
204
+ target.to_a if target.respond_to?(:to_a)
205
+ end
206
+
207
+ :"#{reflection.name.to_s.singularize}_ids"
208
+ end
209
+
210
+ input(attribute, options.merge(:reflection => reflection))
211
+ end
212
+
213
+ # Creates a button:
214
+ #
215
+ # form_for @user do |f|
216
+ # f.button :submit
217
+ # end
218
+ #
219
+ # It just acts as a proxy to method name given. We also alias original Rails
220
+ # button implementation (3.2 forward (to delegate to the original when
221
+ # calling `f.button :button`.
222
+ #
223
+ # TODO: remove if condition when supporting only Rails 3.2 forward.
224
+ alias_method :button_button, :button if method_defined?(:button)
225
+ def button(type, *args, &block)
226
+ options = args.extract_options!.dup
227
+ options[:class] = [SimpleForm.button_class, options[:class]].compact
228
+ args << options
229
+ if respond_to?("#{type}_button")
230
+ send("#{type}_button", *args, &block)
231
+ else
232
+ send(type, *args, &block)
233
+ end
234
+ end
235
+
236
+ # Creates an error tag based on the given attribute, only when the attribute
237
+ # contains errors. All the given options are sent as :error_html.
238
+ #
239
+ # == Examples
240
+ #
241
+ # f.error :name
242
+ # f.error :name, :id => "cool_error"
243
+ #
244
+ def error(attribute_name, options={})
245
+ options = options.dup
246
+
247
+ options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)
248
+ column = find_attribute_column(attribute_name)
249
+ input_type = default_input_type(attribute_name, column, options)
250
+ wrapper.find(:error).
251
+ render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))
252
+ end
253
+
254
+ # Return the error but also considering its name. This is used
255
+ # when errors for a hidden field need to be shown.
256
+ #
257
+ # == Examples
258
+ #
259
+ # f.full_error :token #=> <span class="error">Token is invalid</span>
260
+ #
261
+ def full_error(attribute_name, options={})
262
+ options = options.dup
263
+
264
+ options[:error_prefix] ||= if object.class.respond_to?(:human_attribute_name)
265
+ object.class.human_attribute_name(attribute_name.to_s)
266
+ else
267
+ attribute_name.to_s.humanize
268
+ end
269
+
270
+ error(attribute_name, options)
271
+ end
272
+
273
+ # Creates a hint tag for the given attribute. Accepts a symbol indicating
274
+ # an attribute for I18n lookup or a string. All the given options are sent
275
+ # as :hint_html.
276
+ #
277
+ # == Examples
278
+ #
279
+ # f.hint :name # Do I18n lookup
280
+ # f.hint :name, :id => "cool_hint"
281
+ # f.hint "Don't forget to accept this"
282
+ #
283
+ def hint(attribute_name, options={})
284
+ options = options.dup
285
+
286
+ options[:hint_html] = options.except(:hint_tag, :hint)
287
+ if attribute_name.is_a?(String)
288
+ options[:hint] = attribute_name
289
+ attribute_name, column, input_type = nil, nil, nil
290
+ else
291
+ column = find_attribute_column(attribute_name)
292
+ input_type = default_input_type(attribute_name, column, options)
293
+ end
294
+
295
+ wrapper.find(:hint).
296
+ render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))
297
+ end
298
+
299
+ # Creates a default label tag for the given attribute. You can give a label
300
+ # through the :label option or using i18n. All the given options are sent
301
+ # as :label_html.
302
+ #
303
+ # == Examples
304
+ #
305
+ # f.label :name # Do I18n lookup
306
+ # f.label :name, "Name" # Same behavior as Rails, do not add required tag
307
+ # f.label :name, :label => "Name" # Same as above, but adds required tag
308
+ #
309
+ # f.label :name, :required => false
310
+ # f.label :name, :id => "cool_label"
311
+ #
312
+ def label(attribute_name, *args)
313
+ return super if args.first.is_a?(String) || block_given?
314
+
315
+ options = args.extract_options!.dup
316
+ options[:label_html] = options.except(:label, :required, :as)
317
+
318
+ column = find_attribute_column(attribute_name)
319
+ input_type = default_input_type(attribute_name, column, options)
320
+ SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).label
321
+ end
322
+
323
+ # Creates an error notification message that only appears when the form object
324
+ # has some error. You can give a specific message with the :message option,
325
+ # otherwise it will look for a message using I18n. All other options given are
326
+ # passed straight as html options to the html tag.
327
+ #
328
+ # == Examples
329
+ #
330
+ # f.error_notification
331
+ # f.error_notification :message => 'Something went wrong'
332
+ # f.error_notification :id => 'user_error_message', :class => 'form_error'
333
+ #
334
+ def error_notification(options={})
335
+ SimpleForm::ErrorNotification.new(self, options).render
336
+ end
337
+
338
+ # Extract the model names from the object_name mess, ignoring numeric and
339
+ # explicit child indexes.
340
+ #
341
+ # Example:
342
+ #
343
+ # route[blocks_attributes][0][blocks_learning_object_attributes][1][foo_attributes]
344
+ # ["route", "blocks", "blocks_learning_object", "foo"]
345
+ #
346
+ def lookup_model_names
347
+ @lookup_model_names ||= begin
348
+ child_index = options[:child_index]
349
+ names = object_name.to_s.scan(/([a-zA-Z_]+)/).flatten
350
+ names.delete(child_index) if child_index
351
+ names.each { |name| name.gsub!('_attributes', '') }
352
+ names.freeze
353
+ end
354
+ end
355
+
356
+ # The action to be used in lookup.
357
+ def lookup_action
358
+ @lookup_action ||= begin
359
+ action = template.controller.action_name
360
+ return unless action
361
+ action = action.to_sym
362
+ ACTIONS[action] || action
363
+ end
364
+ end
365
+
366
+ private
367
+
368
+ # Find an input based on the attribute name.
369
+ def find_input(attribute_name, options={}, &block) #:nodoc:
370
+ column = find_attribute_column(attribute_name)
371
+ input_type = default_input_type(attribute_name, column, options)
372
+
373
+ if input_type == :radio
374
+ SimpleForm.deprecation_warn "Using `:as => :radio` as input type is " \
375
+ "deprecated, please change it to `:as => :radio_buttons`."
376
+ input_type = :radio_buttons
377
+ end
378
+
379
+ if block_given?
380
+ SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block)
381
+ else
382
+ find_mapping(input_type).new(self, attribute_name, column, input_type, options)
383
+ end
384
+ end
385
+
386
+ # Attempt to guess the better input type given the defined options. By
387
+ # default alwayls fallback to the user :as option, or to a :select when a
388
+ # collection is given.
389
+ def default_input_type(attribute_name, column, options) #:nodoc:
390
+ return options[:as].to_sym if options[:as]
391
+ return :select if options[:collection]
392
+ custom_type = find_custom_type(attribute_name.to_s) and return custom_type
393
+
394
+ input_type = column.try(:type)
395
+ case input_type
396
+ when :timestamp
397
+ :datetime
398
+ when :string, nil
399
+ case attribute_name.to_s
400
+ when /password/ then :password
401
+ when /time_zone/ then :time_zone
402
+ when /country/ then :country
403
+ when /email/ then :email
404
+ when /phone/ then :tel
405
+ when /url/ then :url
406
+ else
407
+ file_method?(attribute_name) ? :file : (input_type || :string)
408
+ end
409
+ else
410
+ input_type
411
+ end
412
+ end
413
+
414
+ def find_custom_type(attribute_name) #:nodoc:
415
+ SimpleForm.input_mappings.find { |match, type|
416
+ attribute_name =~ match
417
+ }.try(:last) if SimpleForm.input_mappings
418
+ end
419
+
420
+ def file_method?(attribute_name) #:nodoc:
421
+ file = @object.send(attribute_name) if @object.respond_to?(attribute_name)
422
+ file && SimpleForm.file_methods.any? { |m| file.respond_to?(m) }
423
+ end
424
+
425
+ def find_attribute_column(attribute_name) #:nodoc:
426
+ if @object.respond_to?(:column_for_attribute)
427
+ @object.column_for_attribute(attribute_name)
428
+ end
429
+ end
430
+
431
+ def find_association_reflection(association) #:nodoc:
432
+ if @object.class.respond_to?(:reflect_on_association)
433
+ @object.class.reflect_on_association(association)
434
+ end
435
+ end
436
+
437
+ # Attempts to find a mapping. It follows the following rules:
438
+ #
439
+ # 1) It tries to find a registered mapping, if succeeds:
440
+ # a) Try to find an alternative with the same name in the Object scope
441
+ # b) Or use the found mapping
442
+ # 2) If not, fallbacks to #{input_type}Input
443
+ # 3) If not, fallbacks to SimpleForm::Inputs::#{input_type}Input
444
+ def find_mapping(input_type) #:nodoc:
445
+ discovery_cache[input_type] ||=
446
+ if mapping = self.class.mappings[input_type]
447
+ mapping_override(mapping) || mapping
448
+ else
449
+ camelized = "#{input_type.to_s.camelize}Input"
450
+ attempt_mapping(camelized, Object) || attempt_mapping(camelized, self.class) ||
451
+ raise("No input found for #{input_type}")
452
+ end
453
+ end
454
+
455
+ def find_wrapper_mapping(input_type) #:nodoc:
456
+ SimpleForm.wrapper_mappings && SimpleForm.wrapper_mappings[input_type]
457
+ end
458
+
459
+ # If cache_discovery is enabled, use the class level cache that persists
460
+ # between requests, otherwise use the instance one.
461
+ def discovery_cache #:nodoc:
462
+ if SimpleForm.cache_discovery
463
+ self.class.discovery_cache
464
+ else
465
+ @discovery_cache ||= {}
466
+ end
467
+ end
468
+
469
+ def mapping_override(klass) #:nodoc:
470
+ name = klass.name
471
+ if name =~ /^SimpleForm::Inputs/
472
+ attempt_mapping name.split("::").last, Object
473
+ end
474
+ end
475
+
476
+ def attempt_mapping(mapping, at) #:nodoc:
477
+ return if SimpleForm.inputs_discovery == false && at == Object
478
+
479
+ begin
480
+ at.const_get(mapping)
481
+ rescue NameError => e
482
+ raise if e.message !~ /#{mapping}$/
483
+ end
484
+ end
485
+ end
486
+ end
@@ -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
@@ -68,6 +65,10 @@ module SimpleForm
68
65
  @html_classes = SimpleForm.additional_classes_for(:input) { additional_classes }
69
66
 
70
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
+
71
72
  @input_html_options = html_options_for(:input, input_html_classes).tap do |o|
72
73
  o[:readonly] = true if has_readonly?
73
74
  o[:disabled] = true if has_disabled?
@@ -93,10 +94,6 @@ module SimpleForm
93
94
 
94
95
  private
95
96
 
96
- def add_size!
97
- input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
98
- end
99
-
100
97
  def limit
101
98
  if column
102
99
  decimal_or_float? ? decimal_limit : column_limit
@@ -182,7 +179,7 @@ module SimpleForm
182
179
  lookups << :"defaults.#{reflection_or_attribute_name}"
183
180
  lookups << default
184
181
 
185
- I18n.t(lookups.shift, :scope => :"simple_form.#{namespace}", :default => lookups).presence
182
+ I18n.t(lookups.shift, scope: :"simple_form.#{namespace}", default: lookups).presence
186
183
  end
187
184
  end
188
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
@@ -35,7 +35,7 @@ module SimpleForm
35
35
  # reuse the method for nested boolean style, but with no unchecked value,
36
36
  # which won't generate the hidden checkbox. This is the default functionality
37
37
  # in Rails > 3.2.1, and is backported in SimpleForm AV helpers.
38
- def build_check_box(unchecked_value = unchecked_value())
38
+ def build_check_box(unchecked_value = unchecked_value)
39
39
  @builder.check_box(attribute_name, input_html_options, checked_value, unchecked_value)
40
40
  end
41
41
 
@@ -50,9 +50,10 @@ module SimpleForm
50
50
  # we need the hidden field to be *outside* the label (otherwise it
51
51
  # generates invalid html - html5 only).
52
52
  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])
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)
56
57
  end
57
58
 
58
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
 
@@ -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: :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