formtastic 3.1.3 → 5.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.
- checksums.yaml +7 -0
- data/.gitattributes +1 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +3 -2
- data/CHANGELOG.md +61 -0
- data/Gemfile.lock +140 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +183 -167
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +20 -1
- data/app/assets/stylesheets/formtastic.css +1 -1
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +12 -16
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_6.1/Gemfile +5 -0
- data/gemfiles/rails_7.0/Gemfile +5 -0
- data/gemfiles/rails_7.1/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/action_class_finder.rb +1 -0
- data/lib/formtastic/actions/base.rb +1 -0
- data/lib/formtastic/actions/button_action.rb +1 -0
- data/lib/formtastic/actions/buttonish.rb +1 -0
- data/lib/formtastic/actions/input_action.rb +1 -0
- data/lib/formtastic/actions/link_action.rb +1 -0
- data/lib/formtastic/actions.rb +7 -3
- data/lib/formtastic/deprecation.rb +2 -38
- data/lib/formtastic/engine.rb +4 -1
- data/lib/formtastic/form_builder.rb +12 -24
- data/lib/formtastic/helpers/action_helper.rb +2 -48
- data/lib/formtastic/helpers/actions_helper.rb +1 -0
- data/lib/formtastic/helpers/enum.rb +14 -0
- data/lib/formtastic/helpers/errors_helper.rb +3 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +14 -9
- data/lib/formtastic/helpers/file_column_detection.rb +1 -0
- data/lib/formtastic/helpers/form_helper.rb +2 -1
- data/lib/formtastic/helpers/input_helper.rb +20 -76
- data/lib/formtastic/helpers/inputs_helper.rb +29 -23
- data/lib/formtastic/helpers/reflection.rb +1 -0
- data/lib/formtastic/helpers.rb +2 -2
- data/lib/formtastic/html_attributes.rb +1 -0
- data/lib/formtastic/i18n.rb +2 -1
- data/lib/formtastic/input_class_finder.rb +1 -0
- data/lib/formtastic/inputs/base/associations.rb +1 -0
- data/lib/formtastic/inputs/base/choices.rb +3 -2
- data/lib/formtastic/inputs/base/collections.rb +46 -10
- data/lib/formtastic/inputs/base/database.rb +5 -7
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +1 -0
- data/lib/formtastic/inputs/base/errors.rb +7 -6
- data/lib/formtastic/inputs/base/fileish.rb +1 -0
- data/lib/formtastic/inputs/base/hints.rb +2 -1
- data/lib/formtastic/inputs/base/html.rb +9 -7
- data/lib/formtastic/inputs/base/labelling.rb +3 -2
- data/lib/formtastic/inputs/base/naming.rb +5 -4
- data/lib/formtastic/inputs/base/numeric.rb +1 -0
- data/lib/formtastic/inputs/base/options.rb +3 -3
- data/lib/formtastic/inputs/base/placeholder.rb +1 -0
- data/lib/formtastic/inputs/base/stringish.rb +1 -0
- data/lib/formtastic/inputs/base/timeish.rb +9 -4
- data/lib/formtastic/inputs/base/validations.rb +39 -12
- data/lib/formtastic/inputs/base/wrapping.rb +1 -0
- data/lib/formtastic/inputs/base.rb +3 -2
- data/lib/formtastic/inputs/boolean_input.rb +2 -1
- data/lib/formtastic/inputs/check_boxes_input.rb +15 -6
- data/lib/formtastic/inputs/color_input.rb +1 -1
- data/lib/formtastic/inputs/country_input.rb +4 -1
- data/lib/formtastic/inputs/datalist_input.rb +1 -0
- data/lib/formtastic/inputs/date_picker_input.rb +1 -0
- data/lib/formtastic/inputs/date_select_input.rb +1 -0
- data/lib/formtastic/inputs/datetime_picker_input.rb +1 -0
- data/lib/formtastic/inputs/datetime_select_input.rb +1 -0
- data/lib/formtastic/inputs/email_input.rb +1 -0
- data/lib/formtastic/inputs/file_input.rb +1 -0
- data/lib/formtastic/inputs/hidden_input.rb +3 -2
- data/lib/formtastic/inputs/number_input.rb +1 -0
- data/lib/formtastic/inputs/password_input.rb +1 -0
- data/lib/formtastic/inputs/phone_input.rb +1 -0
- data/lib/formtastic/inputs/radio_input.rb +21 -0
- data/lib/formtastic/inputs/range_input.rb +1 -0
- data/lib/formtastic/inputs/search_input.rb +1 -0
- data/lib/formtastic/inputs/select_input.rb +30 -1
- data/lib/formtastic/inputs/string_input.rb +1 -0
- data/lib/formtastic/inputs/text_input.rb +1 -0
- data/lib/formtastic/inputs/time_picker_input.rb +1 -0
- data/lib/formtastic/inputs/time_select_input.rb +1 -0
- data/lib/formtastic/inputs/time_zone_input.rb +17 -6
- data/lib/formtastic/inputs/url_input.rb +1 -0
- data/lib/formtastic/inputs.rb +33 -29
- data/lib/formtastic/localized_string.rb +1 -0
- data/lib/formtastic/localizer.rb +21 -22
- data/lib/formtastic/namespaced_class_finder.rb +8 -9
- data/lib/formtastic/version.rb +2 -1
- data/lib/formtastic.rb +10 -11
- data/lib/generators/formtastic/form/form_generator.rb +2 -1
- data/lib/generators/formtastic/input/input_generator.rb +47 -0
- data/lib/generators/formtastic/install/install_generator.rb +1 -0
- data/lib/generators/templates/formtastic.rb +15 -13
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +1 -1
- data/script/integration-template.rb +73 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +2 -1
- data/spec/actions/button_action_spec.rb +21 -20
- data/spec/actions/generic_action_spec.rb +134 -133
- data/spec/actions/input_action_spec.rb +20 -19
- data/spec/actions/link_action_spec.rb +30 -29
- data/spec/builder/custom_builder_spec.rb +39 -22
- data/spec/builder/error_proc_spec.rb +6 -5
- data/spec/builder/semantic_fields_for_spec.rb +46 -45
- data/spec/fast_spec_helper.rb +13 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +33 -32
- data/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +10 -9
- data/spec/helpers/action_helper_spec.rb +329 -10
- data/spec/helpers/actions_helper_spec.rb +43 -42
- data/spec/helpers/form_helper_spec.rb +45 -38
- data/spec/helpers/input_helper_spec.rb +976 -2
- data/spec/helpers/inputs_helper_spec.rb +217 -202
- data/spec/helpers/reflection_helper_spec.rb +7 -6
- data/spec/helpers/semantic_errors_helper_spec.rb +26 -25
- data/spec/i18n_spec.rb +30 -29
- data/spec/input_class_finder_spec.rb +2 -1
- data/spec/inputs/base/collections_spec.rb +78 -0
- data/spec/inputs/base/validations_spec.rb +481 -0
- data/spec/inputs/boolean_input_spec.rb +73 -72
- data/spec/inputs/check_boxes_input_spec.rb +169 -121
- data/spec/inputs/color_input_spec.rb +53 -64
- data/spec/inputs/country_input_spec.rb +23 -22
- data/spec/inputs/custom_input_spec.rb +3 -6
- data/spec/inputs/datalist_input_spec.rb +3 -2
- data/spec/inputs/date_picker_input_spec.rb +114 -113
- data/spec/inputs/date_select_input_spec.rb +76 -61
- data/spec/inputs/datetime_picker_input_spec.rb +123 -122
- data/spec/inputs/datetime_select_input_spec.rb +85 -68
- data/spec/inputs/email_input_spec.rb +17 -16
- data/spec/inputs/file_input_spec.rb +18 -17
- data/spec/inputs/hidden_input_spec.rb +32 -31
- data/spec/inputs/include_blank_spec.rb +10 -9
- data/spec/inputs/label_spec.rb +26 -25
- data/spec/inputs/number_input_spec.rb +212 -211
- data/spec/inputs/password_input_spec.rb +17 -16
- data/spec/inputs/phone_input_spec.rb +17 -16
- data/spec/inputs/placeholder_spec.rb +18 -17
- data/spec/inputs/radio_input_spec.rb +92 -65
- data/spec/inputs/range_input_spec.rb +136 -135
- data/spec/inputs/readonly_spec.rb +51 -0
- data/spec/inputs/search_input_spec.rb +16 -15
- data/spec/inputs/select_input_spec.rb +209 -102
- data/spec/inputs/string_input_spec.rb +51 -50
- data/spec/inputs/text_input_spec.rb +34 -33
- data/spec/inputs/time_picker_input_spec.rb +115 -114
- data/spec/inputs/time_select_input_spec.rb +84 -70
- data/spec/inputs/time_zone_input_spec.rb +58 -31
- data/spec/inputs/url_input_spec.rb +17 -16
- data/spec/inputs/with_options_spec.rb +9 -8
- data/spec/localizer_spec.rb +18 -17
- data/spec/namespaced_class_finder_spec.rb +18 -6
- data/spec/schema.rb +22 -0
- data/spec/spec_helper.rb +172 -260
- data/spec/support/custom_macros.rb +74 -76
- data/spec/support/deprecation.rb +2 -1
- data/spec/support/shared_examples.rb +2 -1233
- data/spec/support/specialized_class_finder_shared_example.rb +1 -0
- data/spec/support/test_environment.rb +24 -9
- metadata +78 -170
- data/.travis.yml +0 -29
- data/Appraisals +0 -29
- data/CHANGELOG +0 -39
- data/DEPRECATIONS +0 -49
- data/gemfiles/rails_3.2.gemfile +0 -7
- data/gemfiles/rails_4.0.4.gemfile +0 -7
- data/gemfiles/rails_4.1.gemfile +0 -7
- data/gemfiles/rails_4.2.gemfile +0 -7
- data/gemfiles/rails_4.gemfile +0 -7
- data/gemfiles/rails_edge.gemfile +0 -10
- data/lib/formtastic/util.rb +0 -57
- data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
- data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
- data/spec/support/deferred_garbage_collection.rb +0 -21
- data/spec/util_spec.rb +0 -66
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
module Base
|
|
4
5
|
module Naming
|
|
5
6
|
|
|
6
7
|
def as
|
|
7
|
-
self.class.name.split("::").
|
|
8
|
+
self.class.name.split("::")[-1].underscore.gsub(/_input$/, '')
|
|
8
9
|
end
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
def sanitized_object_name
|
|
11
12
|
object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
|
12
13
|
end
|
|
@@ -18,7 +19,7 @@ module Formtastic
|
|
|
18
19
|
def attributized_method_name
|
|
19
20
|
method.to_s.gsub(/_id$/, '').to_sym
|
|
20
21
|
end
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
def humanized_method_name
|
|
23
24
|
if builder.label_str_method != :humanize
|
|
24
25
|
# Special case where label_str_method should trump the human_attribute_name
|
|
@@ -39,4 +40,4 @@ module Formtastic
|
|
|
39
40
|
end
|
|
40
41
|
end
|
|
41
42
|
end
|
|
42
|
-
end
|
|
43
|
+
end
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
module Base
|
|
4
5
|
module Options
|
|
5
|
-
|
|
6
|
+
|
|
6
7
|
def input_options
|
|
7
8
|
options.except(*formtastic_options)
|
|
8
9
|
end
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
def formtastic_options
|
|
11
12
|
[:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :value_as_class, :class]
|
|
12
13
|
end
|
|
13
|
-
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
module Base
|
|
@@ -85,6 +86,9 @@ module Formtastic
|
|
|
85
86
|
# <%= f.input :publish_at, :as => :time_select, :include_blank => true %>
|
|
86
87
|
# <%= f.input :publish_at, :as => :time_select, :include_blank => false %>
|
|
87
88
|
#
|
|
89
|
+
# @example Provide a value for the field via selected
|
|
90
|
+
# <%= f.input :publish_at, :as => :datetime_select, :selected => DateTime.new(2018, 10, 4, 12, 00)
|
|
91
|
+
#
|
|
88
92
|
# @todo Document i18n
|
|
89
93
|
# @todo Check what other Rails options are supported (`start_year`, `end_year`, `use_month_numbers`, `use_short_month`, `add_month_numbers`, `prompt`), write tests for them, and otherwise support them
|
|
90
94
|
# @todo Could we take the rendering from Rails' helpers and inject better HTML in and around it rather than re-inventing the whee?
|
|
@@ -153,10 +157,11 @@ module Formtastic
|
|
|
153
157
|
|
|
154
158
|
def fragment_label_html(fragment)
|
|
155
159
|
text = fragment_label(fragment)
|
|
156
|
-
text.blank? ? "".html_safe : template.content_tag(:label, text, :for => fragment_id(fragment))
|
|
160
|
+
text.blank? ? +"".html_safe : template.content_tag(:label, text, :for => fragment_id(fragment))
|
|
157
161
|
end
|
|
158
162
|
|
|
159
163
|
def value
|
|
164
|
+
return input_options[:selected] if options.key?(:selected)
|
|
160
165
|
object.send(method) if object && object.respond_to?(method)
|
|
161
166
|
end
|
|
162
167
|
|
|
@@ -213,7 +218,7 @@ module Formtastic
|
|
|
213
218
|
:class => "label"
|
|
214
219
|
)
|
|
215
220
|
else
|
|
216
|
-
"".html_safe
|
|
221
|
+
+"".html_safe
|
|
217
222
|
end
|
|
218
223
|
end
|
|
219
224
|
|
|
@@ -224,7 +229,7 @@ module Formtastic
|
|
|
224
229
|
end
|
|
225
230
|
|
|
226
231
|
def hidden_fragments
|
|
227
|
-
"".html_safe
|
|
232
|
+
+"".html_safe
|
|
228
233
|
end
|
|
229
234
|
|
|
230
235
|
def hidden_field_name(fragment)
|
|
@@ -238,4 +243,4 @@ module Formtastic
|
|
|
238
243
|
end
|
|
239
244
|
end
|
|
240
245
|
end
|
|
241
|
-
end
|
|
246
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
module Base
|
|
@@ -73,13 +74,11 @@ module Formtastic
|
|
|
73
74
|
raise IndeterminableMinimumAttributeError if validation.options[:greater_than] && column? && [:float, :decimal].include?(column.type)
|
|
74
75
|
|
|
75
76
|
if validation.options[:greater_than_or_equal_to]
|
|
76
|
-
return (validation.options[:greater_than_or_equal_to]
|
|
77
|
-
return (validation.options[:greater_than_or_equal_to])
|
|
77
|
+
return option_value(validation.options[:greater_than_or_equal_to], object)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
if validation.options[:greater_than]
|
|
81
|
-
return (validation.options[:greater_than]
|
|
82
|
-
return (validation.options[:greater_than] + 1)
|
|
81
|
+
return option_value(validation.options[:greater_than], object) + 1
|
|
83
82
|
end
|
|
84
83
|
end
|
|
85
84
|
end
|
|
@@ -94,13 +93,11 @@ module Formtastic
|
|
|
94
93
|
raise IndeterminableMaximumAttributeError if validation.options[:less_than] && column? && [:float, :decimal].include?(column.type)
|
|
95
94
|
|
|
96
95
|
if validation.options[:less_than_or_equal_to]
|
|
97
|
-
return (validation.options[:less_than_or_equal_to]
|
|
98
|
-
return (validation.options[:less_than_or_equal_to])
|
|
96
|
+
return option_value(validation.options[:less_than_or_equal_to], object)
|
|
99
97
|
end
|
|
100
98
|
|
|
101
99
|
if validation.options[:less_than]
|
|
102
|
-
return (
|
|
103
|
-
return (validation.options[:less_than] - 1)
|
|
100
|
+
return option_value(validation.options[:less_than], object) - 1
|
|
104
101
|
end
|
|
105
102
|
end
|
|
106
103
|
end
|
|
@@ -136,9 +133,10 @@ module Formtastic
|
|
|
136
133
|
return true if options[:required] == true
|
|
137
134
|
return false if not_required_through_negated_validation?
|
|
138
135
|
if validations?
|
|
139
|
-
validations.
|
|
136
|
+
validations.any? { |validator|
|
|
140
137
|
if validator.options.key?(:on)
|
|
141
|
-
|
|
138
|
+
validator_on = Array(validator.options[:on])
|
|
139
|
+
next false if (validator_on.exclude?(:save)) && ((object.new_record? && validator_on.exclude?(:create)) || (!object.new_record? && validator_on.exclude?(:update)))
|
|
142
140
|
end
|
|
143
141
|
case validator.kind
|
|
144
142
|
when :presence
|
|
@@ -152,7 +150,7 @@ module Formtastic
|
|
|
152
150
|
else
|
|
153
151
|
false
|
|
154
152
|
end
|
|
155
|
-
}
|
|
153
|
+
}
|
|
156
154
|
else
|
|
157
155
|
return responds_to_global_required? && !!builder.all_fields_required_by_default
|
|
158
156
|
end
|
|
@@ -192,8 +190,37 @@ module Formtastic
|
|
|
192
190
|
validation_limit || column_limit
|
|
193
191
|
end
|
|
194
192
|
|
|
193
|
+
def readonly?
|
|
194
|
+
readonly_from_options? || readonly_attribute?
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def readonly_attribute?
|
|
198
|
+
object_class = self.object.class
|
|
199
|
+
object_class.respond_to?(:readonly_attributes) &&
|
|
200
|
+
self.object.persisted? &&
|
|
201
|
+
column.respond_to?(:name) &&
|
|
202
|
+
object_class.readonly_attributes.include?(column.name.to_s)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def readonly_from_options?
|
|
206
|
+
options[:input_html] && options[:input_html][:readonly]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
private
|
|
210
|
+
|
|
211
|
+
# Loosely based on
|
|
212
|
+
# https://github.com/rails/rails/blob/459e7cf62252558bbf65f582a230562ab1a76c5e/activemodel/lib/active_model/validations/numericality.rb#L65-L70
|
|
213
|
+
def option_value(option, object)
|
|
214
|
+
case option
|
|
215
|
+
when Symbol
|
|
216
|
+
object.send(option)
|
|
217
|
+
when Proc
|
|
218
|
+
option.call(object)
|
|
219
|
+
else
|
|
220
|
+
option
|
|
221
|
+
end
|
|
222
|
+
end
|
|
195
223
|
end
|
|
196
224
|
end
|
|
197
225
|
end
|
|
198
226
|
end
|
|
199
|
-
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
module Base
|
|
@@ -21,7 +22,7 @@ module Formtastic
|
|
|
21
22
|
# Usefull for deprecating options.
|
|
22
23
|
def warn_and_correct_option!(old_option_name, new_option_name)
|
|
23
24
|
if options.key?(old_option_name)
|
|
24
|
-
|
|
25
|
+
Deprecation.warn("The :#{old_option_name} option is deprecated in favour of :#{new_option_name} and will be removed from Formtastic in the next version", caller(6))
|
|
25
26
|
options[new_option_name] = options.delete(old_option_name)
|
|
26
27
|
end
|
|
27
28
|
end
|
|
@@ -29,7 +30,7 @@ module Formtastic
|
|
|
29
30
|
# Usefull for deprecating options.
|
|
30
31
|
def warn_deprecated_option!(old_option_name, instructions)
|
|
31
32
|
if options.key?(old_option_name)
|
|
32
|
-
|
|
33
|
+
Deprecation.warn("The :#{old_option_name} option is deprecated in favour of `#{instructions}`. :#{old_option_name} will be removed in the next version", caller(6))
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
# Boolean inputs are used to render an input for a single checkbox, typically for attributes
|
|
@@ -59,7 +60,7 @@ module Formtastic
|
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
def label_text_with_embedded_checkbox
|
|
62
|
-
check_box_html << "" << label_text
|
|
63
|
+
check_box_html << +"" << label_text
|
|
63
64
|
end
|
|
64
65
|
|
|
65
66
|
def check_box_html
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
|
|
@@ -69,6 +70,11 @@ module Formtastic
|
|
|
69
70
|
include Base::Collections
|
|
70
71
|
include Base::Choices
|
|
71
72
|
|
|
73
|
+
def initialize(*args)
|
|
74
|
+
super
|
|
75
|
+
raise Formtastic::UnsupportedEnumCollection if collection_from_enum?
|
|
76
|
+
end
|
|
77
|
+
|
|
72
78
|
def to_html
|
|
73
79
|
input_wrapping do
|
|
74
80
|
choices_wrapping do
|
|
@@ -94,8 +100,8 @@ module Formtastic
|
|
|
94
100
|
end
|
|
95
101
|
|
|
96
102
|
def hidden_field_for_all
|
|
97
|
-
if
|
|
98
|
-
''
|
|
103
|
+
if hidden_fields_for_every?
|
|
104
|
+
+''
|
|
99
105
|
else
|
|
100
106
|
options = {}
|
|
101
107
|
options[:class] = [method.to_s.singularize, 'default'].join('_') if value_as_class?
|
|
@@ -104,7 +110,7 @@ module Formtastic
|
|
|
104
110
|
end
|
|
105
111
|
end
|
|
106
112
|
|
|
107
|
-
def
|
|
113
|
+
def hidden_fields_for_every?
|
|
108
114
|
options[:hidden_fields]
|
|
109
115
|
end
|
|
110
116
|
|
|
@@ -165,7 +171,7 @@ module Formtastic
|
|
|
165
171
|
protected
|
|
166
172
|
|
|
167
173
|
def checkbox_input(choice)
|
|
168
|
-
if
|
|
174
|
+
if hidden_fields_for_every?
|
|
169
175
|
check_box_with_hidden_input(choice)
|
|
170
176
|
else
|
|
171
177
|
check_box_without_hidden_input(choice)
|
|
@@ -175,11 +181,14 @@ module Formtastic
|
|
|
175
181
|
def make_selected_values
|
|
176
182
|
if object.respond_to?(method)
|
|
177
183
|
selected_items = object.send(method)
|
|
178
|
-
|
|
179
184
|
# Construct an array from the return value, regardless of the return type
|
|
180
185
|
selected_items = [*selected_items].compact.flatten
|
|
181
186
|
|
|
182
|
-
|
|
187
|
+
selected = []
|
|
188
|
+
selected_items.map do |selected_item|
|
|
189
|
+
selected_item_id = selected_item.id if selected_item.respond_to? :id
|
|
190
|
+
item = send_or_call_or_object(value_method, selected_item) || selected_item_id
|
|
191
|
+
end.compact
|
|
183
192
|
else
|
|
184
193
|
[]
|
|
185
194
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
|
|
@@ -31,7 +32,6 @@ module Formtastic
|
|
|
31
32
|
include Base::Placeholder
|
|
32
33
|
|
|
33
34
|
def to_html
|
|
34
|
-
raise "The :color input requires the color_field form helper, which is only available in Rails 4+" unless builder.respond_to?(:color_field)
|
|
35
35
|
input_wrapping do
|
|
36
36
|
label_html <<
|
|
37
37
|
builder.color_field(method, input_html_options)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
# Outputs a country select input, wrapping around a regular country_select helper.
|
|
@@ -67,8 +68,10 @@ module Formtastic
|
|
|
67
68
|
class CountryInput
|
|
68
69
|
include Base
|
|
69
70
|
|
|
71
|
+
CountrySelectPluginMissing = Class.new(StandardError)
|
|
72
|
+
|
|
70
73
|
def to_html
|
|
71
|
-
raise "To use the :country input, please install a country_select plugin, like this one: https://github.com/stefanpenner/country_select" unless builder.respond_to?(:country_select)
|
|
74
|
+
raise CountrySelectPluginMissing, "To use the :country input, please install a country_select plugin, like this one: https://github.com/stefanpenner/country_select" unless builder.respond_to?(:country_select)
|
|
72
75
|
input_wrapping do
|
|
73
76
|
label_html <<
|
|
74
77
|
builder.country_select(method, priority_countries, input_options, input_html_options)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
|
|
@@ -42,7 +43,7 @@ module Formtastic
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
def error_html
|
|
45
|
-
""
|
|
46
|
+
+""
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def errors?
|
|
@@ -50,7 +51,7 @@ module Formtastic
|
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
def hint_html
|
|
53
|
-
""
|
|
54
|
+
+""
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
def hint?
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
|
|
@@ -31,6 +32,10 @@ module Formtastic
|
|
|
31
32
|
# `Section.all` for a `Post` form with an input for a `belongs_to :section` association.
|
|
32
33
|
# You can override or customise this collection through the `:collection` option (see examples).
|
|
33
34
|
#
|
|
35
|
+
# For radio inputs that map to ActiveRecord `enum` attributes, Formtastic will automatically
|
|
36
|
+
# load in your enum options to be used as the radio button choices. This can be overridden with
|
|
37
|
+
# the `:collection` option, or augmented with I18n translations. See examples below.
|
|
38
|
+
#
|
|
34
39
|
# The way on which Formtastic renders the `value` attribute and label for each choice in the `:collection` is
|
|
35
40
|
# customisable (see examples below). When not provided, we fall back to a list of methods to try on each
|
|
36
41
|
# object such as `:to_label`, `:name` and `:to_s`, which are defined in the configurations
|
|
@@ -100,6 +105,22 @@ module Formtastic
|
|
|
100
105
|
# @example Set HTML options on a specific radio input option with a 3rd element in the array for a collection member
|
|
101
106
|
# <%= f.input :author, :as => :radio, :collection => [["Test", 'test'], ["Try", "try", {:disabled => true}]]
|
|
102
107
|
#
|
|
108
|
+
# @example Using ActiveRecord enum attribute with i18n translation:
|
|
109
|
+
# # post.rb
|
|
110
|
+
# class Post < ActiveRecord::Base
|
|
111
|
+
# enum :status => [ :active, :archived ]
|
|
112
|
+
# end
|
|
113
|
+
# # en.yml
|
|
114
|
+
# en:
|
|
115
|
+
# activerecord:
|
|
116
|
+
# attributes:
|
|
117
|
+
# post:
|
|
118
|
+
# statuses:
|
|
119
|
+
# active: I am active!
|
|
120
|
+
# archived: I am archived!
|
|
121
|
+
# # form
|
|
122
|
+
# <%= f.input :status, :as => :radio %>
|
|
123
|
+
#
|
|
103
124
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
104
125
|
# @see Formtastic::Inputs::RadioInput as an alternative for `belongs_to` associations
|
|
105
126
|
#
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
# A select input is used to render a `<select>` tag with a series of options to choose from.
|
|
@@ -8,6 +9,7 @@ module Formtastic
|
|
|
8
9
|
# This is the default input choice when:
|
|
9
10
|
#
|
|
10
11
|
# * the database column type is an `:integer` and there is an association (`belongs_to`)
|
|
12
|
+
# * the database column type is an `:integer` and there is an enum defined (`enum`)
|
|
11
13
|
# * the database column type is a `:string` and the `:collection` option is used
|
|
12
14
|
# * there an object with an association, but no database column on the object (`has_many`, etc)
|
|
13
15
|
# * there is no object and the `:collection` option is used
|
|
@@ -38,6 +40,13 @@ module Formtastic
|
|
|
38
40
|
# `:to_s`, which are defined in the configurations `collection_label_methods` and
|
|
39
41
|
# `collection_value_methods` (see examples below).
|
|
40
42
|
#
|
|
43
|
+
# For select inputs that map to ActiveRecord `enum` attributes, Formtastic will automatically
|
|
44
|
+
# load in your enum options to be used as the select's options. This can be overridden with
|
|
45
|
+
# the `:collection` option, or augmented with I18n translations. See examples below.
|
|
46
|
+
# An error is raised if you try to render a multi-select with an enum, as ActiveRecord can
|
|
47
|
+
# only store one choice in the database.
|
|
48
|
+
#
|
|
49
|
+
#
|
|
41
50
|
# @example Basic `belongs_to` example with full form context
|
|
42
51
|
#
|
|
43
52
|
# <%= semantic_form_for @post do |f| %>
|
|
@@ -124,6 +133,21 @@ module Formtastic
|
|
|
124
133
|
# <%= f.input :author, :as => :select, :prompt => true %> => <option value="">Please select</option>
|
|
125
134
|
# <%= f.input :author, :as => :select, :prompt => "Please select an author" %>
|
|
126
135
|
#
|
|
136
|
+
# @example Using ActiveRecord enum attribute with i18n translation:
|
|
137
|
+
# # post.rb
|
|
138
|
+
# class Post < ActiveRecord::Base
|
|
139
|
+
# enum :status => [ :active, :archived ]
|
|
140
|
+
# end
|
|
141
|
+
# # en.yml
|
|
142
|
+
# en:
|
|
143
|
+
# activerecord:
|
|
144
|
+
# attributes:
|
|
145
|
+
# post:
|
|
146
|
+
# statuses:
|
|
147
|
+
# active: I am active!
|
|
148
|
+
# archived: I am archived!
|
|
149
|
+
# # form
|
|
150
|
+
# <%= f.input :status, :as => :select %>
|
|
127
151
|
#
|
|
128
152
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
129
153
|
# @see Formtastic::Inputs::CheckBoxesInput CheckBoxesInput as an alternative for `has_many` and `has_and_belongs_to_many` associations
|
|
@@ -134,6 +158,11 @@ module Formtastic
|
|
|
134
158
|
include Base
|
|
135
159
|
include Base::Collections
|
|
136
160
|
|
|
161
|
+
def initialize(*args)
|
|
162
|
+
super
|
|
163
|
+
raise Formtastic::UnsupportedEnumCollection if collection_from_enum? && multiple?
|
|
164
|
+
end
|
|
165
|
+
|
|
137
166
|
def to_html
|
|
138
167
|
input_wrapping do
|
|
139
168
|
label_html <<
|
|
@@ -168,7 +197,7 @@ module Formtastic
|
|
|
168
197
|
def extra_input_html_options
|
|
169
198
|
{
|
|
170
199
|
:multiple => multiple?,
|
|
171
|
-
:name =>
|
|
200
|
+
:name => multiple? ? input_html_options_name_multiple : input_html_options_name
|
|
172
201
|
}
|
|
173
202
|
|
|
174
203
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Formtastic
|
|
2
3
|
module Inputs
|
|
3
4
|
|
|
@@ -28,9 +29,19 @@ module Formtastic
|
|
|
28
29
|
#
|
|
29
30
|
# @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
|
|
30
31
|
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
|
|
32
|
+
# The priority_zones option:
|
|
33
|
+
# Since this input actually uses Rails' `time_zone_select` helper, the :priority_zones
|
|
34
|
+
# option needs to be an array of ActiveSupport::TimeZone objects.
|
|
35
|
+
#
|
|
36
|
+
# And you can configure default value using
|
|
37
|
+
#
|
|
38
|
+
# ```
|
|
39
|
+
# Formtastic::FormBuilder.priority_time_zones = [timezone1, timezone2]
|
|
40
|
+
# ```
|
|
41
|
+
#
|
|
42
|
+
# See http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/time_zone_select for more information.
|
|
43
|
+
#
|
|
44
|
+
class TimeZoneInput
|
|
34
45
|
include Base
|
|
35
46
|
|
|
36
47
|
def to_html
|
|
@@ -39,10 +50,10 @@ module Formtastic
|
|
|
39
50
|
builder.time_zone_select(method, priority_zones, input_options, input_html_options)
|
|
40
51
|
end
|
|
41
52
|
end
|
|
42
|
-
|
|
53
|
+
|
|
43
54
|
def priority_zones
|
|
44
|
-
options[:priority_zones] ||
|
|
55
|
+
options[:priority_zones] || Formtastic::FormBuilder.priority_time_zones
|
|
45
56
|
end
|
|
46
57
|
end
|
|
47
58
|
end
|
|
48
|
-
end
|
|
59
|
+
end
|