comfy_bootstrap_form 4.0.0.beta1

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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +621 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/stylesheets/rails_bootstrap_forms.css +10 -0
  6. data/lib/bootstrap_form.rb +13 -0
  7. data/lib/bootstrap_form/aliasing.rb +35 -0
  8. data/lib/bootstrap_form/form_builder.rb +460 -0
  9. data/lib/bootstrap_form/helper.rb +36 -0
  10. data/lib/bootstrap_form/helpers/bootstrap.rb +94 -0
  11. data/lib/bootstrap_form/helpers/nested_form.rb +33 -0
  12. data/lib/bootstrap_form/version.rb +3 -0
  13. data/lib/comfy_bootstrap_form.rb +1 -0
  14. data/test/bootstrap_checkbox_test.rb +144 -0
  15. data/test/bootstrap_fields_test.rb +152 -0
  16. data/test/bootstrap_form_group_test.rb +313 -0
  17. data/test/bootstrap_form_test.rb +276 -0
  18. data/test/bootstrap_other_components_test.rb +86 -0
  19. data/test/bootstrap_radio_button_test.rb +124 -0
  20. data/test/bootstrap_selects_test.rb +160 -0
  21. data/test/dummy/Gemfile +45 -0
  22. data/test/dummy/Gemfile.lock +120 -0
  23. data/test/dummy/README.rdoc +28 -0
  24. data/test/dummy/Rakefile +10 -0
  25. data/test/dummy/app/assets/javascripts/application.js +16 -0
  26. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  27. data/test/dummy/app/controllers/application_controller.rb +5 -0
  28. data/test/dummy/app/helpers/application_helper.rb +2 -0
  29. data/test/dummy/app/models/address.rb +3 -0
  30. data/test/dummy/app/models/faux_user.rb +9 -0
  31. data/test/dummy/app/models/super_user.rb +2 -0
  32. data/test/dummy/app/models/user.rb +9 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/bin/bundle +3 -0
  35. data/test/dummy/bin/rails +4 -0
  36. data/test/dummy/bin/rake +4 -0
  37. data/test/dummy/config.ru +4 -0
  38. data/test/dummy/config/application.rb +23 -0
  39. data/test/dummy/config/boot.rb +4 -0
  40. data/test/dummy/config/database.yml +25 -0
  41. data/test/dummy/config/environment.rb +5 -0
  42. data/test/dummy/config/environments/development.rb +29 -0
  43. data/test/dummy/config/environments/production.rb +80 -0
  44. data/test/dummy/config/environments/test.rb +53 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  47. data/test/dummy/config/initializers/generic_migration.rb +6 -0
  48. data/test/dummy/config/initializers/inflections.rb +16 -0
  49. data/test/dummy/config/initializers/mime_types.rb +5 -0
  50. data/test/dummy/config/initializers/secret_token.rb +12 -0
  51. data/test/dummy/config/initializers/session_store.rb +3 -0
  52. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  53. data/test/dummy/config/locales/en.yml +23 -0
  54. data/test/dummy/config/routes.rb +3 -0
  55. data/test/dummy/db/migrate/20130703191909_create_users.rb +13 -0
  56. data/test/dummy/db/migrate/20130703191937_create_addresses.rb +13 -0
  57. data/test/dummy/db/migrate/20130912171202_add_preferences_to_user.rb +5 -0
  58. data/test/dummy/db/migrate/20140327190145_add_terms_to_user.rb +5 -0
  59. data/test/dummy/db/migrate/20140922133133_add_type_to_users.rb +5 -0
  60. data/test/dummy/db/schema.rb +38 -0
  61. data/test/dummy/db/seeds.rb +7 -0
  62. data/test/dummy/db/test.sqlite3 +0 -0
  63. data/test/dummy/log/test.log +18394 -0
  64. data/test/dummy/public/404.html +58 -0
  65. data/test/dummy/public/422.html +58 -0
  66. data/test/dummy/public/500.html +57 -0
  67. data/test/dummy/public/favicon.ico +0 -0
  68. data/test/dummy/public/robots.txt +5 -0
  69. data/test/dummy/test/fixtures/addresses.yml +15 -0
  70. data/test/dummy/test/fixtures/users.yml +15 -0
  71. data/test/dummy/test/models/address_test.rb +7 -0
  72. data/test/dummy/test/models/user_test.rb +7 -0
  73. data/test/dummy/test/test_helper.rb +15 -0
  74. data/test/special_form_class_models_test.rb +43 -0
  75. data/test/test_helper.rb +86 -0
  76. metadata +309 -0
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'BootstrapForm'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
35
+
36
+
37
+ task :default => :test
@@ -0,0 +1,10 @@
1
+ .rails-bootstrap-forms-date-select select,
2
+ .rails-bootstrap-forms-time-select select,
3
+ .rails-bootstrap-forms-datetime-select select {
4
+ display: inline-block;
5
+ width: auto;
6
+ }
7
+
8
+ .rails-bootstrap-forms-error-summary {
9
+ margin-top: 10px;
10
+ }
@@ -0,0 +1,13 @@
1
+ require 'bootstrap_form/form_builder'
2
+ require 'bootstrap_form/helper'
3
+
4
+ module BootstrapForm
5
+ module Rails
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+
11
+ ActiveSupport.on_load(:action_view) do
12
+ include BootstrapForm::Helper
13
+ end
@@ -0,0 +1,35 @@
1
+ module BootstrapForm
2
+ # This module implements the old ActiveSupport alias_method_chain feature
3
+ # with a new name, and without the deprecation warnings. In ActiveSupport 5+,
4
+ # this style of patching was deprecated in favor of Module.prepend. But
5
+ # Module.prepend is not present in Ruby 1.9, which we would still like to
6
+ # support. So we continue to use of alias_method_chain, albeit with a
7
+ # different name to avoid collisions.
8
+ module Aliasing
9
+ # This code is copied and pasted from ActiveSupport, but with :bootstrap
10
+ # hardcoded as the feature name, and with the deprecation warning removed.
11
+ def bootstrap_method_alias(target)
12
+ feature = :bootstrap
13
+
14
+ # Strip out punctuation on predicates, bang or writer methods since
15
+ # e.g. target?_without_feature is not a valid method name.
16
+ aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
17
+ yield(aliased_target, punctuation) if block_given?
18
+
19
+ with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
20
+ without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
21
+
22
+ alias_method without_method, target
23
+ alias_method target, with_method
24
+
25
+ case
26
+ when public_method_defined?(without_method)
27
+ public target
28
+ when protected_method_defined?(without_method)
29
+ protected target
30
+ when private_method_defined?(without_method)
31
+ private target
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,460 @@
1
+ require_relative 'aliasing'
2
+ require_relative 'helpers/bootstrap'
3
+
4
+ module BootstrapForm
5
+ class FormBuilder < ActionView::Helpers::FormBuilder
6
+ extend BootstrapForm::Aliasing
7
+ include BootstrapForm::Helpers::Bootstrap
8
+
9
+ attr_reader :layout, :label_col, :control_col, :has_error, :inline_errors, :label_errors, :acts_like_form_tag
10
+
11
+ FIELD_HELPERS = %w{color_field date_field datetime_field datetime_local_field
12
+ email_field month_field number_field password_field phone_field
13
+ range_field search_field telephone_field text_area text_field time_field
14
+ url_field week_field}
15
+
16
+ DATE_SELECT_HELPERS = %w{date_select time_select datetime_select}
17
+
18
+ delegate :content_tag, :capture, :concat, to: :@template
19
+
20
+ def initialize(object_name, object, template, options)
21
+ @layout = options[:layout]
22
+ @label_col = options[:label_col] || default_label_col
23
+ @control_col = options[:control_col] || default_control_col
24
+ @label_errors = options[:label_errors] || false
25
+ @inline_errors = if options[:inline_errors].nil?
26
+ @label_errors != true
27
+ else
28
+ options[:inline_errors] != false
29
+ end
30
+ @acts_like_form_tag = options[:acts_like_form_tag]
31
+
32
+ super
33
+ end
34
+
35
+ FIELD_HELPERS.each do |method_name|
36
+ with_method_name = "#{method_name}_with_bootstrap"
37
+ without_method_name = "#{method_name}_without_bootstrap"
38
+
39
+ define_method(with_method_name) do |name, options = {}|
40
+ form_group_builder(name, options) do
41
+ prepend_and_append_input(options) do
42
+ send(without_method_name, name, options)
43
+ end
44
+ end
45
+ end
46
+
47
+ bootstrap_method_alias method_name
48
+ end
49
+
50
+ DATE_SELECT_HELPERS.each do |method_name|
51
+ with_method_name = "#{method_name}_with_bootstrap"
52
+ without_method_name = "#{method_name}_without_bootstrap"
53
+
54
+ define_method(with_method_name) do |name, options = {}, html_options = {}|
55
+ form_group_builder(name, options, html_options) do
56
+ content_tag(:div, send(without_method_name, name, options, html_options), class: control_specific_class(method_name))
57
+ end
58
+ end
59
+
60
+ bootstrap_method_alias method_name
61
+ end
62
+
63
+ def file_field_with_bootstrap(name, options = {})
64
+ form_group_builder(name, options.reverse_merge(control_class: nil)) do
65
+ file_field_without_bootstrap(name, options)
66
+ end
67
+ end
68
+
69
+ bootstrap_method_alias :file_field
70
+
71
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("4.1.0")
72
+ def select_with_bootstrap(method, choices = nil, options = {}, html_options = {}, &block)
73
+ form_group_builder(method, options, html_options) do
74
+ prepend_and_append_input(options) do
75
+ select_without_bootstrap(method, choices, options, html_options, &block)
76
+ end
77
+ end
78
+ end
79
+ else
80
+ def select_with_bootstrap(method, choices, options = {}, html_options = {})
81
+ form_group_builder(method, options, html_options) do
82
+ prepend_and_append_input(options) do
83
+ select_without_bootstrap(method, choices, options, html_options)
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ bootstrap_method_alias :select
90
+
91
+ def collection_select_with_bootstrap(method, collection, value_method, text_method, options = {}, html_options = {})
92
+ form_group_builder(method, options, html_options) do
93
+ collection_select_without_bootstrap(method, collection, value_method, text_method, options, html_options)
94
+ end
95
+ end
96
+
97
+ bootstrap_method_alias :collection_select
98
+
99
+ def grouped_collection_select_with_bootstrap(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
100
+ form_group_builder(method, options, html_options) do
101
+ grouped_collection_select_without_bootstrap(method, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
102
+ end
103
+ end
104
+
105
+ bootstrap_method_alias :grouped_collection_select
106
+
107
+ def time_zone_select_with_bootstrap(method, priority_zones = nil, options = {}, html_options = {})
108
+ form_group_builder(method, options, html_options) do
109
+ time_zone_select_without_bootstrap(method, priority_zones, options, html_options)
110
+ end
111
+ end
112
+
113
+ bootstrap_method_alias :time_zone_select
114
+
115
+ def check_box_with_bootstrap(name, options = {}, checked_value = "1", unchecked_value = "0", &block)
116
+ options = options.symbolize_keys!
117
+ check_box_options = options.except(:label, :label_class, :help, :inline)
118
+ check_box_options[:class] = ["form-check-input", check_box_options[:class]].compact.join(' ')
119
+
120
+ html = check_box_without_bootstrap(name, check_box_options, checked_value, unchecked_value)
121
+ label_content = block_given? ? capture(&block) : options[:label]
122
+ html.concat(" ").concat(label_content || (object && object.class.human_attribute_name(name)) || name.to_s.humanize)
123
+
124
+ label_name = name
125
+ # label's `for` attribute needs to match checkbox tag's id,
126
+ # IE sanitized value, IE
127
+ # https://github.com/rails/rails/blob/c57e7239a8b82957bcb07534cb7c1a3dcef71864/actionview/lib/action_view/helpers/tags/base.rb#L116-L118
128
+ if options[:multiple]
129
+ label_name =
130
+ "#{name}_#{checked_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase}"
131
+ end
132
+
133
+ disabled_class = " disabled" if options[:disabled]
134
+ label_class = options[:label_class]
135
+
136
+ if options[:inline]
137
+ label_class = " #{label_class}" if label_class
138
+ label(label_name, html, class: "form-check-inline#{disabled_class}#{label_class}")
139
+ else
140
+ content_tag(:div, class: "form-check#{disabled_class}") do
141
+ label(label_name, html, class: ["form-check-label", label_class].compact.join(" "))
142
+ end
143
+ end
144
+ end
145
+
146
+ bootstrap_method_alias :check_box
147
+
148
+ def radio_button_with_bootstrap(name, value, *args)
149
+ options = args.extract_options!.symbolize_keys!
150
+ args << options.except(:label, :label_class, :help, :inline)
151
+
152
+ html = radio_button_without_bootstrap(name, value, *args) + " " + options[:label]
153
+
154
+ disabled_class = " disabled" if options[:disabled]
155
+ label_class = options[:label_class]
156
+
157
+ if options[:inline]
158
+ label_class = " #{label_class}" if label_class
159
+ label(name, html, class: "radio-inline#{disabled_class}#{label_class}", value: value)
160
+ else
161
+ content_tag(:div, class: "radio#{disabled_class}") do
162
+ label(name, html, value: value, class: label_class)
163
+ end
164
+ end
165
+ end
166
+
167
+ bootstrap_method_alias :radio_button
168
+
169
+ def collection_check_boxes_with_bootstrap(*args)
170
+ html = inputs_collection(*args) do |name, value, options|
171
+ options[:multiple] = true
172
+ check_box(name, options, value, nil)
173
+ end
174
+ hidden_field(args.first,{value: "", multiple: true}).concat(html)
175
+ end
176
+
177
+ bootstrap_method_alias :collection_check_boxes
178
+
179
+ def collection_radio_buttons_with_bootstrap(*args)
180
+ inputs_collection(*args) do |name, value, options|
181
+ radio_button(name, value, options)
182
+ end
183
+ end
184
+
185
+ bootstrap_method_alias :collection_radio_buttons
186
+
187
+ def check_boxes_collection(*args)
188
+ warn "'BootstrapForm#check_boxes_collection' is deprecated, use 'BootstrapForm#collection_check_boxes' instead"
189
+ collection_check_boxes(*args)
190
+ end
191
+
192
+ def radio_buttons_collection(*args)
193
+ warn "'BootstrapForm#radio_buttons_collection' is deprecated, use 'BootstrapForm#collection_radio_buttons' instead"
194
+ collection_radio_buttons(*args)
195
+ end
196
+
197
+ def form_group(*args, &block)
198
+ options = args.extract_options!
199
+ name = args.first
200
+
201
+ options[:class] = ["form-group", options[:class]].compact.join(' ')
202
+ options[:class] << " row" if get_group_layout(options[:layout]) == :horizontal
203
+ options[:class] << " #{error_class}" if has_error?(name)
204
+ options[:class] << " #{feedback_class}" if options[:icon]
205
+
206
+ content_tag(:div, options.except(:id, :label, :help, :icon, :label_col, :control_col, :layout)) do
207
+ label = generate_label(options[:id], name, options[:label], options[:label_col], options[:layout]) if options[:label]
208
+ control = capture(&block).to_s
209
+ control.concat(generate_help(name, options[:help]).to_s)
210
+ control.concat(generate_icon(options[:icon])) if options[:icon]
211
+
212
+ if get_group_layout(options[:layout]) == :horizontal
213
+ control_class = options[:control_col] || control_col
214
+ unless options[:label]
215
+ control_offset = offset_col(options[:label_col] || @label_col)
216
+ control_class = "#{control_class} #{control_offset}"
217
+ end
218
+ control = content_tag(:div, control, class: control_class)
219
+ end
220
+
221
+ concat(label).concat(control)
222
+ end
223
+ end
224
+
225
+ def fields_for_with_bootstrap(record_name, record_object = nil, fields_options = {}, &block)
226
+ fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
227
+ fields_options[:layout] ||= options[:layout]
228
+ fields_options[:label_col] = fields_options[:label_col].present? ? "#{fields_options[:label_col]} #{label_class}" : options[:label_col]
229
+ fields_options[:control_col] ||= options[:control_col]
230
+ fields_options[:inline_errors] ||= options[:inline_errors]
231
+ fields_options[:label_errors] ||= options[:label_errors]
232
+ fields_for_without_bootstrap(record_name, record_object, fields_options, &block)
233
+ end
234
+
235
+ bootstrap_method_alias :fields_for
236
+
237
+ private
238
+
239
+ def horizontal?
240
+ layout == :horizontal
241
+ end
242
+
243
+ def get_group_layout(group_layout)
244
+ group_layout || layout
245
+ end
246
+
247
+ def default_label_col
248
+ "col-sm-2"
249
+ end
250
+
251
+ def offset_col(label_col)
252
+ label_col.sub(/^col-(\w+)-(\d)$/, 'col-\1-offset-\2')
253
+ end
254
+
255
+ def default_control_col
256
+ "col-sm-10"
257
+ end
258
+
259
+ def hide_class
260
+ "sr-only" # still accessible for screen readers
261
+ end
262
+
263
+ def control_class
264
+ "form-control"
265
+ end
266
+
267
+ def label_class
268
+ "form-control-label"
269
+ end
270
+
271
+ def error_class
272
+ "has-danger"
273
+ end
274
+
275
+ def feedback_class
276
+ "has-feedback"
277
+ end
278
+
279
+ def control_specific_class(method)
280
+ "rails-bootstrap-forms-#{method.gsub(/_/, "-")}"
281
+ end
282
+
283
+ def has_error?(name)
284
+ object.respond_to?(:errors) && !(name.nil? || object.errors[name].empty?)
285
+ end
286
+
287
+ def required_attribute?(obj, attribute)
288
+
289
+ return false unless obj and attribute
290
+
291
+ target = (obj.class == Class) ? obj : obj.class
292
+
293
+ target_validators = if target.respond_to? :validators_on
294
+ target.validators_on(attribute).map(&:class)
295
+ else
296
+ []
297
+ end
298
+
299
+ has_presence_validator = target_validators.include?(
300
+ ActiveModel::Validations::PresenceValidator)
301
+
302
+ if defined? ActiveRecord::Validations::PresenceValidator
303
+ has_presence_validator |= target_validators.include?(
304
+ ActiveRecord::Validations::PresenceValidator)
305
+ end
306
+
307
+ has_presence_validator
308
+ end
309
+
310
+ def form_group_builder(method, options, html_options = nil)
311
+ options.symbolize_keys!
312
+ html_options.symbolize_keys! if html_options
313
+
314
+ # Add control_class; allow it to be overridden by :control_class option
315
+ css_options = html_options || options
316
+ control_classes = css_options.delete(:control_class) { control_class }
317
+ css_options[:class] = [control_classes, css_options[:class]].compact.join(" ")
318
+ css_options[:class] << " is-invalid" if has_error?(method)
319
+
320
+ options = convert_form_tag_options(method, options) if acts_like_form_tag
321
+
322
+ wrapper_class = css_options.delete(:wrapper_class)
323
+ wrapper_options = css_options.delete(:wrapper)
324
+ help = options.delete(:help)
325
+ icon = options.delete(:icon)
326
+ label_col = options.delete(:label_col)
327
+ control_col = options.delete(:control_col)
328
+ layout = get_group_layout(options.delete(:layout))
329
+ form_group_options = {
330
+ id: options[:id],
331
+ help: help,
332
+ icon: icon,
333
+ label_col: label_col,
334
+ control_col: control_col,
335
+ layout: layout,
336
+ class: wrapper_class
337
+ }
338
+
339
+ if wrapper_options.is_a?(Hash)
340
+ form_group_options.merge!(wrapper_options)
341
+ end
342
+
343
+ unless options.delete(:skip_label)
344
+ if options[:label].is_a?(Hash)
345
+ label_text = options[:label].delete(:text)
346
+ label_class = options[:label].delete(:class)
347
+ options.delete(:label)
348
+ end
349
+ label_class ||= options.delete(:label_class)
350
+ label_class = hide_class if options.delete(:hide_label)
351
+
352
+ if options[:label].is_a?(String)
353
+ label_text ||= options.delete(:label)
354
+ end
355
+
356
+ form_group_options.merge!(label: {
357
+ text: label_text,
358
+ class: label_class,
359
+ skip_required: options.delete(:skip_required)
360
+ })
361
+ end
362
+
363
+ form_group(method, form_group_options) do
364
+ yield
365
+ end
366
+ end
367
+
368
+ def convert_form_tag_options(method, options = {})
369
+ options[:name] ||= method
370
+ options[:id] ||= method
371
+ options
372
+ end
373
+
374
+ def generate_label(id, name, options, custom_label_col, group_layout)
375
+ options[:for] = id if acts_like_form_tag
376
+ classes = [options[:class], label_class]
377
+ classes << (custom_label_col || label_col) if get_group_layout(group_layout) == :horizontal
378
+ unless options.delete(:skip_required)
379
+ classes << "required" if required_attribute?(object, name)
380
+ end
381
+
382
+ options[:class] = classes.compact.join(" ")
383
+
384
+ if label_errors && has_error?(name)
385
+ error_messages = get_error_messages(name)
386
+ label_text = (options[:text] || object.class.human_attribute_name(name)).to_s.concat(" #{error_messages}")
387
+ label(name, label_text, options.except(:text))
388
+ else
389
+ label(name, options[:text], options.except(:text))
390
+ end
391
+
392
+ end
393
+
394
+ def generate_help(name, help_text)
395
+ if has_error?(name) && inline_errors
396
+ help_text = get_error_messages(name)
397
+ help_klass = 'invalid-feedback'
398
+ end
399
+ return if help_text == false
400
+
401
+ help_klass ||= 'form-text text-muted'
402
+ help_text ||= get_help_text_by_i18n_key(name)
403
+
404
+ content_tag(:span, help_text, class: help_klass) if help_text.present?
405
+ end
406
+
407
+ def generate_icon(icon)
408
+ content_tag(:span, "", class: "glyphicon glyphicon-#{icon} form-control-feedback")
409
+ end
410
+
411
+ def get_error_messages(name)
412
+ object.errors[name].join(", ")
413
+ end
414
+
415
+ def inputs_collection(name, collection, value, text, options = {}, &block)
416
+ form_group_builder(name, options) do
417
+ inputs = ""
418
+
419
+ collection.each do |obj|
420
+ input_options = options.merge(label: text.respond_to?(:call) ? text.call(obj) : obj.send(text))
421
+
422
+ input_value = value.respond_to?(:call) ? value.call(obj) : obj.send(value)
423
+ if checked = input_options[:checked]
424
+ input_options[:checked] = checked == input_value ||
425
+ Array(checked).try(:include?, input_value) ||
426
+ checked == obj ||
427
+ Array(checked).try(:include?, obj)
428
+ end
429
+
430
+ input_options.delete(:class)
431
+ inputs << block.call(name, input_value, input_options)
432
+ end
433
+
434
+ inputs.html_safe
435
+ end
436
+ end
437
+
438
+ def get_help_text_by_i18n_key(name)
439
+ if object
440
+
441
+ if object.class.respond_to?(:model_name)
442
+ # ActiveModel::Naming 3.X.X does not support .name; it is supported as of 4.X.X
443
+ partial_scope = object.class.model_name.respond_to?(:name) ? object.class.model_name.name : object.class.model_name
444
+ else
445
+ partial_scope = object.class.name
446
+ end
447
+
448
+ underscored_scope = "activerecord.help.#{partial_scope.underscore}"
449
+ downcased_scope = "activerecord.help.#{partial_scope.downcase}"
450
+ help_text = I18n.t(name, scope: underscored_scope, default: '').presence
451
+ help_text ||= if text = I18n.t(name, scope: downcased_scope, default: '').presence
452
+ warn "I18n key '#{downcased_scope}.#{name}' is deprecated, use '#{underscored_scope}.#{name}' instead"
453
+ text
454
+ end
455
+ help_text
456
+ end
457
+ end
458
+
459
+ end
460
+ end