mega-safe-tool 0.0.1

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 (171) hide show
  1. checksums.yaml +7 -0
  2. data/formtastic-6.0.0/Appraisals +23 -0
  3. data/formtastic-6.0.0/CONTRIBUTING.md +27 -0
  4. data/formtastic-6.0.0/Gemfile +8 -0
  5. data/formtastic-6.0.0/MIT-LICENSE +20 -0
  6. data/formtastic-6.0.0/README.md +600 -0
  7. data/formtastic-6.0.0/RELEASE_PROCESS +7 -0
  8. data/formtastic-6.0.0/Rakefile +54 -0
  9. data/formtastic-6.0.0/bin/appraisal +8 -0
  10. data/formtastic-6.0.0/formtastic.gemspec +45 -0
  11. data/formtastic-6.0.0/gemfiles/rails_72.gemfile +9 -0
  12. data/formtastic-6.0.0/gemfiles/rails_80.gemfile +9 -0
  13. data/formtastic-6.0.0/gemfiles/rails_81.gemfile +9 -0
  14. data/formtastic-6.0.0/gemfiles/rails_edge.gemfile +9 -0
  15. data/formtastic-6.0.0/lib/formtastic/action_class_finder.rb +19 -0
  16. data/formtastic-6.0.0/lib/formtastic/actions/base.rb +157 -0
  17. data/formtastic-6.0.0/lib/formtastic/actions/button_action.rb +68 -0
  18. data/formtastic-6.0.0/lib/formtastic/actions/buttonish.rb +18 -0
  19. data/formtastic-6.0.0/lib/formtastic/actions/input_action.rb +71 -0
  20. data/formtastic-6.0.0/lib/formtastic/actions/link_action.rb +89 -0
  21. data/formtastic-6.0.0/lib/formtastic/actions.rb +15 -0
  22. data/formtastic-6.0.0/lib/formtastic/deprecation.rb +6 -0
  23. data/formtastic-6.0.0/lib/formtastic/form_builder.rb +109 -0
  24. data/formtastic-6.0.0/lib/formtastic/helpers/action_helper.rb +115 -0
  25. data/formtastic-6.0.0/lib/formtastic/helpers/actions_helper.rb +169 -0
  26. data/formtastic-6.0.0/lib/formtastic/helpers/enum.rb +14 -0
  27. data/formtastic-6.0.0/lib/formtastic/helpers/errors_helper.rb +139 -0
  28. data/formtastic-6.0.0/lib/formtastic/helpers/fieldset_wrapper.rb +85 -0
  29. data/formtastic-6.0.0/lib/formtastic/helpers/file_column_detection.rb +17 -0
  30. data/formtastic-6.0.0/lib/formtastic/helpers/form_helper.rb +204 -0
  31. data/formtastic-6.0.0/lib/formtastic/helpers/input_helper.rb +349 -0
  32. data/formtastic-6.0.0/lib/formtastic/helpers/inputs_helper.rb +421 -0
  33. data/formtastic-6.0.0/lib/formtastic/helpers/reflection.rb +38 -0
  34. data/formtastic-6.0.0/lib/formtastic/helpers.rb +16 -0
  35. data/formtastic-6.0.0/lib/formtastic/html_attributes.rb +33 -0
  36. data/formtastic-6.0.0/lib/formtastic/i18n.rb +33 -0
  37. data/formtastic-6.0.0/lib/formtastic/input_class_finder.rb +19 -0
  38. data/formtastic-6.0.0/lib/formtastic/inputs/base/aria.rb +26 -0
  39. data/formtastic-6.0.0/lib/formtastic/inputs/base/associations.rb +32 -0
  40. data/formtastic-6.0.0/lib/formtastic/inputs/base/choices.rb +109 -0
  41. data/formtastic-6.0.0/lib/formtastic/inputs/base/collections.rb +158 -0
  42. data/formtastic-6.0.0/lib/formtastic/inputs/base/database.rb +20 -0
  43. data/formtastic-6.0.0/lib/formtastic/inputs/base/datetime_pickerish.rb +86 -0
  44. data/formtastic-6.0.0/lib/formtastic/inputs/base/errors.rb +59 -0
  45. data/formtastic-6.0.0/lib/formtastic/inputs/base/fileish.rb +24 -0
  46. data/formtastic-6.0.0/lib/formtastic/inputs/base/hints.rb +32 -0
  47. data/formtastic-6.0.0/lib/formtastic/inputs/base/html.rb +54 -0
  48. data/formtastic-6.0.0/lib/formtastic/inputs/base/labelling.rb +53 -0
  49. data/formtastic-6.0.0/lib/formtastic/inputs/base/naming.rb +43 -0
  50. data/formtastic-6.0.0/lib/formtastic/inputs/base/numeric.rb +51 -0
  51. data/formtastic-6.0.0/lib/formtastic/inputs/base/options.rb +18 -0
  52. data/formtastic-6.0.0/lib/formtastic/inputs/base/placeholder.rb +18 -0
  53. data/formtastic-6.0.0/lib/formtastic/inputs/base/stringish.rb +39 -0
  54. data/formtastic-6.0.0/lib/formtastic/inputs/base/timeish.rb +246 -0
  55. data/formtastic-6.0.0/lib/formtastic/inputs/base/validations.rb +250 -0
  56. data/formtastic-6.0.0/lib/formtastic/inputs/base/wrapping.rb +51 -0
  57. data/formtastic-6.0.0/lib/formtastic/inputs/base.rb +79 -0
  58. data/formtastic-6.0.0/lib/formtastic/inputs/boolean_input.rb +119 -0
  59. data/formtastic-6.0.0/lib/formtastic/inputs/check_boxes_input.rb +198 -0
  60. data/formtastic-6.0.0/lib/formtastic/inputs/color_input.rb +42 -0
  61. data/formtastic-6.0.0/lib/formtastic/inputs/country_input.rb +90 -0
  62. data/formtastic-6.0.0/lib/formtastic/inputs/datalist_input.rb +42 -0
  63. data/formtastic-6.0.0/lib/formtastic/inputs/date_picker_input.rb +94 -0
  64. data/formtastic-6.0.0/lib/formtastic/inputs/date_select_input.rb +35 -0
  65. data/formtastic-6.0.0/lib/formtastic/inputs/datetime_picker_input.rb +104 -0
  66. data/formtastic-6.0.0/lib/formtastic/inputs/datetime_select_input.rb +13 -0
  67. data/formtastic-6.0.0/lib/formtastic/inputs/email_input.rb +42 -0
  68. data/formtastic-6.0.0/lib/formtastic/inputs/file_input.rb +43 -0
  69. data/formtastic-6.0.0/lib/formtastic/inputs/hidden_input.rb +63 -0
  70. data/formtastic-6.0.0/lib/formtastic/inputs/number_input.rb +89 -0
  71. data/formtastic-6.0.0/lib/formtastic/inputs/password_input.rb +42 -0
  72. data/formtastic-6.0.0/lib/formtastic/inputs/phone_input.rb +43 -0
  73. data/formtastic-6.0.0/lib/formtastic/inputs/radio_input.rb +164 -0
  74. data/formtastic-6.0.0/lib/formtastic/inputs/range_input.rb +96 -0
  75. data/formtastic-6.0.0/lib/formtastic/inputs/search_input.rb +42 -0
  76. data/formtastic-6.0.0/lib/formtastic/inputs/select_input.rb +236 -0
  77. data/formtastic-6.0.0/lib/formtastic/inputs/string_input.rb +37 -0
  78. data/formtastic-6.0.0/lib/formtastic/inputs/text_input.rb +49 -0
  79. data/formtastic-6.0.0/lib/formtastic/inputs/time_picker_input.rb +100 -0
  80. data/formtastic-6.0.0/lib/formtastic/inputs/time_select_input.rb +39 -0
  81. data/formtastic-6.0.0/lib/formtastic/inputs/time_zone_input.rb +59 -0
  82. data/formtastic-6.0.0/lib/formtastic/inputs/url_input.rb +42 -0
  83. data/formtastic-6.0.0/lib/formtastic/inputs.rb +43 -0
  84. data/formtastic-6.0.0/lib/formtastic/localized_string.rb +18 -0
  85. data/formtastic-6.0.0/lib/formtastic/localizer.rb +151 -0
  86. data/formtastic-6.0.0/lib/formtastic/namespaced_class_finder.rb +98 -0
  87. data/formtastic-6.0.0/lib/formtastic/version.rb +4 -0
  88. data/formtastic-6.0.0/lib/formtastic.rb +48 -0
  89. data/formtastic-6.0.0/lib/generators/formtastic/form/form_generator.rb +111 -0
  90. data/formtastic-6.0.0/lib/generators/formtastic/input/input_generator.rb +47 -0
  91. data/formtastic-6.0.0/lib/generators/formtastic/install/install_generator.rb +23 -0
  92. data/formtastic-6.0.0/lib/generators/formtastic/stylesheets/stylesheets_generator.rb +15 -0
  93. data/formtastic-6.0.0/lib/generators/templates/_form.html.erb +11 -0
  94. data/formtastic-6.0.0/lib/generators/templates/_form.html.haml +8 -0
  95. data/formtastic-6.0.0/lib/generators/templates/_form.html.slim +8 -0
  96. data/formtastic-6.0.0/lib/generators/templates/formtastic.css +289 -0
  97. data/formtastic-6.0.0/lib/generators/templates/formtastic.rb +118 -0
  98. data/formtastic-6.0.0/lib/generators/templates/input.rb +19 -0
  99. data/formtastic-6.0.0/lib/locale/en.yml +10 -0
  100. data/formtastic-6.0.0/sample/basic_inputs.html +224 -0
  101. data/formtastic-6.0.0/sample/config.ru +69 -0
  102. data/formtastic-6.0.0/sample/index.html +14 -0
  103. data/formtastic-6.0.0/script/integration-template.rb +76 -0
  104. data/formtastic-6.0.0/script/integration.sh +32 -0
  105. data/formtastic-6.0.0/spec/action_class_finder_spec.rb +12 -0
  106. data/formtastic-6.0.0/spec/actions/button_action_spec.rb +63 -0
  107. data/formtastic-6.0.0/spec/actions/generic_action_spec.rb +521 -0
  108. data/formtastic-6.0.0/spec/actions/input_action_spec.rb +59 -0
  109. data/formtastic-6.0.0/spec/actions/link_action_spec.rb +92 -0
  110. data/formtastic-6.0.0/spec/builder/custom_builder_spec.rb +132 -0
  111. data/formtastic-6.0.0/spec/builder/error_proc_spec.rb +27 -0
  112. data/formtastic-6.0.0/spec/builder/semantic_fields_for_spec.rb +213 -0
  113. data/formtastic-6.0.0/spec/fast_spec_helper.rb +12 -0
  114. data/formtastic-6.0.0/spec/generators/formtastic/form/form_generator_spec.rb +132 -0
  115. data/formtastic-6.0.0/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
  116. data/formtastic-6.0.0/spec/generators/formtastic/install/install_generator_spec.rb +48 -0
  117. data/formtastic-6.0.0/spec/generators/formtastic/stylesheets/stylesheets_generator_spec.rb +22 -0
  118. data/formtastic-6.0.0/spec/helpers/action_helper_spec.rb +338 -0
  119. data/formtastic-6.0.0/spec/helpers/actions_helper_spec.rb +143 -0
  120. data/formtastic-6.0.0/spec/helpers/form_helper_spec.rb +224 -0
  121. data/formtastic-6.0.0/spec/helpers/input_helper_spec.rb +991 -0
  122. data/formtastic-6.0.0/spec/helpers/inputs_helper_spec.rb +669 -0
  123. data/formtastic-6.0.0/spec/helpers/reflection_helper_spec.rb +32 -0
  124. data/formtastic-6.0.0/spec/helpers/semantic_errors_helper_spec.rb +220 -0
  125. data/formtastic-6.0.0/spec/i18n_spec.rb +210 -0
  126. data/formtastic-6.0.0/spec/input_class_finder_spec.rb +10 -0
  127. data/formtastic-6.0.0/spec/inputs/base/collections_spec.rb +119 -0
  128. data/formtastic-6.0.0/spec/inputs/base/validations_spec.rb +481 -0
  129. data/formtastic-6.0.0/spec/inputs/boolean_input_spec.rb +254 -0
  130. data/formtastic-6.0.0/spec/inputs/check_boxes_input_spec.rb +547 -0
  131. data/formtastic-6.0.0/spec/inputs/color_input_spec.rb +85 -0
  132. data/formtastic-6.0.0/spec/inputs/country_input_spec.rb +133 -0
  133. data/formtastic-6.0.0/spec/inputs/custom_input_spec.rb +51 -0
  134. data/formtastic-6.0.0/spec/inputs/datalist_input_spec.rb +61 -0
  135. data/formtastic-6.0.0/spec/inputs/date_picker_input_spec.rb +449 -0
  136. data/formtastic-6.0.0/spec/inputs/date_select_input_spec.rb +249 -0
  137. data/formtastic-6.0.0/spec/inputs/datetime_picker_input_spec.rb +490 -0
  138. data/formtastic-6.0.0/spec/inputs/datetime_select_input_spec.rb +209 -0
  139. data/formtastic-6.0.0/spec/inputs/email_input_spec.rb +85 -0
  140. data/formtastic-6.0.0/spec/inputs/file_input_spec.rb +89 -0
  141. data/formtastic-6.0.0/spec/inputs/hidden_input_spec.rb +135 -0
  142. data/formtastic-6.0.0/spec/inputs/include_blank_spec.rb +78 -0
  143. data/formtastic-6.0.0/spec/inputs/label_spec.rb +181 -0
  144. data/formtastic-6.0.0/spec/inputs/number_input_spec.rb +815 -0
  145. data/formtastic-6.0.0/spec/inputs/password_input_spec.rb +99 -0
  146. data/formtastic-6.0.0/spec/inputs/phone_input_spec.rb +85 -0
  147. data/formtastic-6.0.0/spec/inputs/placeholder_spec.rb +71 -0
  148. data/formtastic-6.0.0/spec/inputs/radio_input_spec.rb +326 -0
  149. data/formtastic-6.0.0/spec/inputs/range_input_spec.rb +505 -0
  150. data/formtastic-6.0.0/spec/inputs/readonly_spec.rb +50 -0
  151. data/formtastic-6.0.0/spec/inputs/search_input_spec.rb +84 -0
  152. data/formtastic-6.0.0/spec/inputs/select_input_spec.rb +661 -0
  153. data/formtastic-6.0.0/spec/inputs/string_input_spec.rb +326 -0
  154. data/formtastic-6.0.0/spec/inputs/text_input_spec.rb +187 -0
  155. data/formtastic-6.0.0/spec/inputs/time_picker_input_spec.rb +455 -0
  156. data/formtastic-6.0.0/spec/inputs/time_select_input_spec.rb +261 -0
  157. data/formtastic-6.0.0/spec/inputs/time_zone_input_spec.rb +143 -0
  158. data/formtastic-6.0.0/spec/inputs/url_input_spec.rb +85 -0
  159. data/formtastic-6.0.0/spec/inputs/with_options_spec.rb +43 -0
  160. data/formtastic-6.0.0/spec/localizer_spec.rb +130 -0
  161. data/formtastic-6.0.0/spec/namespaced_class_finder_spec.rb +90 -0
  162. data/formtastic-6.0.0/spec/schema.rb +22 -0
  163. data/formtastic-6.0.0/spec/spec.opts +2 -0
  164. data/formtastic-6.0.0/spec/spec_helper.rb +466 -0
  165. data/formtastic-6.0.0/spec/support/custom_macros.rb +570 -0
  166. data/formtastic-6.0.0/spec/support/deprecation.rb +7 -0
  167. data/formtastic-6.0.0/spec/support/shared_examples.rb +13 -0
  168. data/formtastic-6.0.0/spec/support/specialized_class_finder_shared_example.rb +27 -0
  169. data/formtastic-6.0.0/spec/support/test_environment.rb +46 -0
  170. data/mega-safe-tool.gemspec +11 -0
  171. metadata +209 -0
@@ -0,0 +1,421 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ module Helpers
4
+
5
+ # {#inputs} is used to wrap a series of form items in a `<fieldset>` and `<ol>`, with each item
6
+ # in the list containing the markup representing a single {#input}.
7
+ #
8
+ # {#inputs} is usually called with a block containing a series of {#input} methods:
9
+ #
10
+ # <%= semantic_form_for @post do |f| %>
11
+ # <%= f.inputs do %>
12
+ # <%= f.input :title %>
13
+ # <%= f.input :body %>
14
+ # <% end %>
15
+ # <% end %>
16
+ #
17
+ # The HTML output will be something like:
18
+ #
19
+ # <form class="formtastic" method="post" action="...">
20
+ # <fieldset>
21
+ # <ol>
22
+ # <li class="string required" id="post_title_input">
23
+ # ...
24
+ # </li>
25
+ # <li class="text required" id="post_body_input">
26
+ # ...
27
+ # </li>
28
+ # </ol>
29
+ # </fieldset>
30
+ # </form>
31
+ #
32
+ # It's important to note that the `semantic_form_for` and {#inputs} blocks wrap the
33
+ # standard Rails `form_for` helper and FormBuilder, so you have full access to every standard
34
+ # Rails form helper, with any HTML markup and ERB syntax, allowing you to "break free" from
35
+ # Formtastic when it doesn't suit:
36
+ #
37
+ # <%= semantic_form_for @post do |f| %>
38
+ # <%= f.inputs do %>
39
+ # <%= f.input :title %>
40
+ # <li>
41
+ # <%= f.text_area :body %>
42
+ # <li>
43
+ # <% end %>
44
+ # <% end %>
45
+ #
46
+ # @see Formtastic::Helpers::InputHelper#input
47
+ module InputsHelper
48
+ include Formtastic::Helpers::FieldsetWrapper
49
+ include Formtastic::LocalizedString
50
+
51
+ # {#inputs} creates an input fieldset and ol tag wrapping for use around a set of inputs. It can be
52
+ # called either with a block (in which you can do the usual Rails form stuff, HTML, ERB, etc),
53
+ # or with a list of fields (accepting all default arguments and options). These two examples
54
+ # are functionally equivalent:
55
+ #
56
+ # # With a block:
57
+ # <% semantic_form_for @post do |form| %>
58
+ # <% f.inputs do %>
59
+ # <%= f.input :title %>
60
+ # <%= f.input :body %>
61
+ # <% end %>
62
+ # <% end %>
63
+ #
64
+ # # With a list of fields (short hand syntax):
65
+ # <% semantic_form_for @post do |form| %>
66
+ # <%= f.inputs :title, :body %>
67
+ # <% end %>
68
+ #
69
+ # # Output:
70
+ # <form ...>
71
+ # <fieldset class="inputs">
72
+ # <ol>
73
+ # <li class="string">...</li>
74
+ # <li class="text">...</li>
75
+ # </ol>
76
+ # </fieldset>
77
+ # </form>
78
+ #
79
+ # **Quick Forms**
80
+ #
81
+ # Quick, scaffolding-style forms can be easily rendered for rapid early development if called
82
+ # without a block or a field list. In the case an input is rendered for **most** columns in
83
+ # the model's database table (like Rails' scaffolding) plus inputs for some model associations.
84
+ #
85
+ # In this case, all inputs are rendered with default options and arguments. You'll want more
86
+ # control than this in a production application, but it's a great way to get started, then
87
+ # come back later to customise the form with a field list or a block of inputs. Example:
88
+ #
89
+ # <% semantic_form_for @post do |form| %>
90
+ # <%= f.inputs %>
91
+ # <% end %>
92
+ #
93
+ # **Nested Attributes**
94
+ #
95
+ # One of the most complicated parts of Rails forms comes when nesting the inputs for
96
+ # attrinbutes on associated models. Formtastic can take the pain away for many (but not all)
97
+ # situations.
98
+ #
99
+ # Given the following models:
100
+ #
101
+ # # Models
102
+ # class User < ActiveRecord::Base
103
+ # has_one :profile
104
+ # accepts_nested_attributes_for :profile
105
+ # end
106
+ # class Profile < ActiveRecord::Base
107
+ # belongs_to :user
108
+ # end
109
+ #
110
+ # Formtastic provides a helper called `semantic_fields_for`, which wraps around Rails' built-in
111
+ # `fields_for` helper for backwards compatibility with previous versions of Formtastic, and for
112
+ # a consistent method naming API. The following examples are functionally equivalent:
113
+ #
114
+ # <% semantic_form_for @user do |form| %>
115
+ # <%= f.inputs :name, :email %>
116
+ #
117
+ # <% f.semantic_fields_for :profile do |profile| %>
118
+ # <% profile.inputs do %>
119
+ # <%= profile.input :biography %>
120
+ # <%= profile.input :twitter_name %>
121
+ # <% end %>
122
+ # <% end %>
123
+ # <% end %>
124
+ #
125
+ # <% semantic_form_for @user do |form| %>
126
+ # <%= f.inputs :name, :email %>
127
+ #
128
+ # <% f.fields_for :profile do |profile| %>
129
+ # <% profile.inputs do %>
130
+ # <%= profile.input :biography %>
131
+ # <%= profile.input :twitter_name %>
132
+ # <% end %>
133
+ # <% end %>
134
+ # <% end %>
135
+ #
136
+ # {#inputs} also provides a DSL similar to `fields_for` / `semantic_fields_for` to reduce the
137
+ # lines of code a little:
138
+ #
139
+ # <% semantic_form_for @user do |f| %>
140
+ # <%= f.inputs :name, :email %>
141
+ #
142
+ # <% f.inputs :for => :profile do %>
143
+ # <%= profile.input :biography %>
144
+ # <%= profile.input :twitter_name %>
145
+ # <%= profile.input :shoe_size %>
146
+ # <% end %>
147
+ # <% end %>
148
+ #
149
+ # The `:for` option also works with short hand syntax:
150
+ #
151
+ # <% semantic_form_for @post do |form| %>
152
+ # <%= f.inputs :name, :email %>
153
+ # <%= f.inputs :biography, :twitter_name, :shoe_size, :for => :profile %>
154
+ # <% end %>
155
+ #
156
+ # {#inputs} will always create a new `<fieldset>` wrapping, so only use it when it makes sense
157
+ # in the document structure and semantics (using `semantic_fields_for` otherwise).
158
+ #
159
+ # All options except `:name`, `:title` and `:for` will be passed down to the fieldset as HTML
160
+ # attributes (id, class, style, etc).
161
+ #
162
+ # When nesting `inputs()` inside another `inputs()` block, the nested content will
163
+ # automatically be wrapped in an `<li>` tag to preserve the HTML validity (a `<fieldset>`
164
+ # cannot be a direct descendant of an `<ol>`.
165
+ #
166
+ #
167
+ # @option *args :for [Symbol, ActiveModel, Array]
168
+ # The contents of this option is passed down to Rails' fields_for() helper, so it accepts the same values.
169
+ #
170
+ # @option *args :name [String]
171
+ # The optional name passed into the `<legend>` tag within the fieldset (alias of `:title`)
172
+ #
173
+ # @option *args :title [String]
174
+ # The optional name passed into the `<legend>` tag within the fieldset (alias of `:name`)
175
+ #
176
+ #
177
+ # @example Quick form: Render a scaffold-like set of inputs for automatically guessed attributes and simple associations on the model, with all default arguments and options
178
+ # <% semantic_form_for @post do |form| %>
179
+ # <%= f.inputs %>
180
+ # <% end %>
181
+ #
182
+ # @example Quick form: Skip one or more fields
183
+ # <%= f.inputs :except => [:featured, :something_for_admin_only] %>
184
+ # <%= f.inputs :except => :featured %>
185
+ #
186
+ # @example Short hand: Render inputs for a named set of attributes and simple associations on the model, with all default arguments and options
187
+ # <% semantic_form_for @post do |form| %>
188
+ # <%= f.inputs :title, :body, :user, :categories %>
189
+ # <% end %>
190
+ #
191
+ # @example Block: Render inputs for attributes and simple associations with full control over arguments and options
192
+ # <% semantic_form_for @post do |form| %>
193
+ # <%= f.inputs do %>
194
+ # <%= f.input :title ... %>
195
+ # <%= f.input :body ... %>
196
+ # <%= f.input :user ... %>
197
+ # <%= f.input :categories ... %>
198
+ # <% end %>
199
+ # <% end %>
200
+ #
201
+ # @example Multiple blocks: Render inputs in multiple fieldsets
202
+ # <% semantic_form_for @post do |form| %>
203
+ # <%= f.inputs do %>
204
+ # <%= f.input :title ... %>
205
+ # <%= f.input :body ... %>
206
+ # <% end %>
207
+ # <%= f.inputs do %>
208
+ # <%= f.input :user ... %>
209
+ # <%= f.input :categories ... %>
210
+ # <% end %>
211
+ # <% end %>
212
+ #
213
+ # @example Provide text for the `<legend>` to name a fieldset (with a block)
214
+ # <% semantic_form_for @post do |form| %>
215
+ # <%= f.inputs :name => 'Write something:' do %>
216
+ # <%= f.input :title ... %>
217
+ # <%= f.input :body ... %>
218
+ # <% end %>
219
+ # <%= f.inputs :name => 'Advanced options:' do %>
220
+ # <%= f.input :user ... %>
221
+ # <%= f.input :categories ... %>
222
+ # <% end %>
223
+ # <% end %>
224
+ #
225
+ # @example Provide text for the `<legend>` to name a fieldset (with short hand)
226
+ # <% semantic_form_for @post do |form| %>
227
+ # <%= f.inputs :title, :body, :name => 'Write something:'%>
228
+ # <%= f.inputs :user, :cateogies, :name => 'Advanced options:' %>
229
+ # <% end %>
230
+ #
231
+ # @example Inputs for nested attributes (don't forget `accepts_nested_attributes_for` in your model, see Rails' `fields_for` documentation)
232
+ # <% semantic_form_for @user do |form| %>
233
+ # <%= f.inputs do %>
234
+ # <%= f.input :name ... %>
235
+ # <%= f.input :email ... %>
236
+ # <% end %>
237
+ # <%= f.inputs :for => :profile do |profile| %>
238
+ # <%= profile.input :user ... %>
239
+ # <%= profile.input :categories ... %>
240
+ # <% end %>
241
+ # <% end %>
242
+ #
243
+ # @example Inputs for nested record (don't forget `accepts_nested_attributes_for` in your model, see Rails' `fields_for` documentation)
244
+ # <% semantic_form_for @user do |form| %>
245
+ # <%= f.inputs do %>
246
+ # <%= f.input :name ... %>
247
+ # <%= f.input :email ... %>
248
+ # <% end %>
249
+ # <%= f.inputs :for => @user.profile do |profile| %>
250
+ # <%= profile.input :user ... %>
251
+ # <%= profile.input :categories ... %>
252
+ # <% end %>
253
+ # <% end %>
254
+ #
255
+ # @example Inputs for nested record with a different name (don't forget `accepts_nested_attributes_for` in your model, see Rails' `fields_for` documentation)
256
+ # <% semantic_form_for @user do |form| %>
257
+ # <%= f.inputs do %>
258
+ # <%= f.input :name ... %>
259
+ # <%= f.input :email ... %>
260
+ # <% end %>
261
+ # <%= f.inputs :for => [:user_profile, @user.profile] do |profile| %>
262
+ # <%= profile.input :user ... %>
263
+ # <%= profile.input :categories ... %>
264
+ # <% end %>
265
+ # <% end %>
266
+ #
267
+ # @example Nesting {#inputs} blocks requires an extra `<li>` tag for valid markup
268
+ # <% semantic_form_for @user do |form| %>
269
+ # <%= f.inputs do %>
270
+ # <%= f.input :name ... %>
271
+ # <%= f.input :email ... %>
272
+ # <li>
273
+ # <%= f.inputs :for => [:user_profile, @user.profile] do |profile| %>
274
+ # <%= profile.input :user ... %>
275
+ # <%= profile.input :categories ... %>
276
+ # <% end %>
277
+ # </li>
278
+ # <% end %>
279
+ # <% end %>
280
+ def inputs(*args, &block)
281
+ wrap_it = @already_in_an_inputs_block ? true : false
282
+ @already_in_an_inputs_block = true
283
+
284
+ title = field_set_title_from_args(*args)
285
+ html_options = args.extract_options!
286
+ html_options[:class] ||= "inputs"
287
+ html_options[:name] = title
288
+ skipped_args = Array.wrap html_options.delete(:except)
289
+
290
+ out = begin
291
+ if html_options[:for] # Nested form
292
+ inputs_for_nested_attributes(*(args << html_options), &block)
293
+ elsif block_given?
294
+ field_set_and_list_wrapping(*(args << html_options), &block)
295
+ else
296
+ legend = args.shift if args.first.is_a?(::String)
297
+ args = default_columns_for_object - skipped_args if @object && args.empty?
298
+ contents = fieldset_contents_from_column_list(args)
299
+ args.unshift(legend) if legend.present?
300
+ field_set_and_list_wrapping(*((args << html_options) << contents))
301
+ end
302
+ end
303
+
304
+ out = template.content_tag(:li, out, :class => "input") if wrap_it
305
+ @already_in_an_inputs_block = wrap_it
306
+ out
307
+ end
308
+
309
+ protected
310
+
311
+ def default_columns_for_object
312
+ cols = association_columns(:belongs_to)
313
+ cols += content_columns
314
+ cols -= skipped_columns
315
+ cols.compact
316
+ end
317
+
318
+ def fieldset_contents_from_column_list(columns)
319
+ columns.collect do |method|
320
+ if @object
321
+ if @object.class.respond_to?(:reflect_on_association)
322
+ if (@object.class.reflect_on_association(method.to_sym) && @object.class.reflect_on_association(method.to_sym).options[:polymorphic] == true)
323
+ raise PolymorphicInputWithoutCollectionError.new("Please provide a collection for :#{method} input (you'll need to use block form syntax). Inputs for polymorphic associations can only be used when an explicit :collection is provided.")
324
+ end
325
+ elsif @object.class.respond_to?(:associations)
326
+ if (@object.class.associations[method.to_sym] && @object.class.associations[method.to_sym].options[:polymorphic] == true)
327
+ raise PolymorphicInputWithoutCollectionError.new("Please provide a collection for :#{method} input (you'll need to use block form syntax). Inputs for polymorphic associations can only be used when an explicit :collection is provided.")
328
+ end
329
+ end
330
+ end
331
+ input(method.to_sym)
332
+ end
333
+ end
334
+
335
+ # Collects association columns (relation columns) for the current form object class. Skips
336
+ # polymorphic associations because we can't guess which class to use for an automatically
337
+ # generated input.
338
+ def association_columns(*by_associations) # @private
339
+ if @object.present? && @object.class.respond_to?(:reflections)
340
+ @object.class.reflections.collect do |name, association_reflection|
341
+ if by_associations.present?
342
+ if by_associations.include?(association_reflection.macro) && association_reflection.options[:polymorphic] != true
343
+ name
344
+ end
345
+ else
346
+ name
347
+ end
348
+ end.compact
349
+ else
350
+ []
351
+ end
352
+ end
353
+
354
+ # Collects all foreign key columns
355
+ def foreign_key_columns # @private
356
+ if @object.present? && @object.class.respond_to?(:reflect_on_all_associations)
357
+ @object.class.reflect_on_all_associations(:belongs_to).map{ |reflection| reflection.foreign_key.to_sym }
358
+ else
359
+ []
360
+ end
361
+ end
362
+
363
+ # Collects content columns (non-relation columns) for the current form object class.
364
+ def content_columns # @private
365
+ # TODO: NameError is raised by Inflector.constantize. Consider checking if it exists instead.
366
+ begin klass = model_name.constantize; rescue NameError; return [] end
367
+ return [] unless klass.respond_to?(:content_columns)
368
+ klass.content_columns.collect { |c| c.name.to_sym }.compact - foreign_key_columns
369
+ end
370
+
371
+ # Deals with :for option when it's supplied to inputs methods. Additional
372
+ # options to be passed down to :for should be supplied using :for_options
373
+ # key.
374
+ #
375
+ # It should raise an error if a block with arity zero is given.
376
+ def inputs_for_nested_attributes(*args, &block) # @private
377
+ options = args.extract_options!
378
+ args << options.merge!(:parent => { :builder => self, :for => options[:for] })
379
+
380
+ fields_for_block = if block_given?
381
+ raise ArgumentError, 'You gave :for option with a block to inputs method, ' +
382
+ 'but the block does not accept any argument.' if block.arity <= 0
383
+ lambda do |f|
384
+ contents = f.inputs(*args) do
385
+ if block.arity == 1 # for backwards compatibility with REE & Ruby 1.8.x
386
+ yield(f)
387
+ else
388
+ index = parent_child_index(options[:parent]) if options[:parent]
389
+ yield(f, index)
390
+ end
391
+ end
392
+ template.concat(contents)
393
+ end
394
+ else
395
+ lambda do |f|
396
+ contents = f.inputs(*args)
397
+ template.concat(contents)
398
+ end
399
+ end
400
+
401
+ fields_for_args = [options.delete(:for), options.delete(:for_options) || {}].flatten(1)
402
+ fields_for(*fields_for_args, &fields_for_block)
403
+ end
404
+
405
+ def field_set_title_from_args(*args) # @private
406
+ options = args.extract_options!
407
+ options[:name] ||= options.delete(:title)
408
+ title = options[:name]
409
+
410
+ if title.blank?
411
+ valid_name_classes = [::String, ::Symbol]
412
+ valid_name_classes.delete(::Symbol) if !block_given? && (args.first.is_a?(::Symbol) && content_columns.include?(args.first))
413
+ title = args.shift if valid_name_classes.any? { |valid_name_class| args.first.is_a?(valid_name_class) }
414
+ end
415
+ title = localized_string(title, title, :title) if title.is_a?(::Symbol)
416
+ title
417
+ end
418
+
419
+ end
420
+ end
421
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ module Helpers
4
+ # @private
5
+ module Reflection
6
+ # If an association method is passed in (f.input :author) try to find the
7
+ # reflection object.
8
+ def reflection_for(method) # @private
9
+ if @object.class.respond_to?(:reflect_on_association)
10
+ @object.class.reflect_on_association(method)
11
+ elsif @object.class.respond_to?(:associations) # MongoMapper uses the 'associations(method)' instead
12
+ @object.class.associations[method]
13
+ end
14
+ end
15
+
16
+ def association_macro_for_method(method) # @private
17
+ reflection = reflection_for(method)
18
+ reflection.macro if reflection
19
+ end
20
+
21
+ def association_primary_key_for_method(method) # @private
22
+ reflection = reflection_for(method)
23
+ if reflection
24
+ case association_macro_for_method(method)
25
+ when :has_and_belongs_to_many, :has_many, :references_and_referenced_in_many, :references_many
26
+ :"#{method.to_s.singularize}_ids"
27
+ else
28
+ return reflection.foreign_key.to_sym if reflection.respond_to?(:foreign_key)
29
+ return reflection.options[:foreign_key].to_sym unless reflection.options[:foreign_key].blank?
30
+ :"#{method}_id"
31
+ end
32
+ else
33
+ method.to_sym
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ module Helpers
4
+ autoload :ActionHelper, 'formtastic/helpers/action_helper'
5
+ autoload :ActionsHelper, 'formtastic/helpers/actions_helper'
6
+ autoload :ErrorsHelper, 'formtastic/helpers/errors_helper'
7
+ autoload :FieldsetWrapper, 'formtastic/helpers/fieldset_wrapper'
8
+ autoload :FileColumnDetection, 'formtastic/helpers/file_column_detection'
9
+ autoload :FormHelper, 'formtastic/helpers/form_helper'
10
+ autoload :InputHelper, 'formtastic/helpers/input_helper'
11
+ autoload :InputsHelper, 'formtastic/helpers/inputs_helper'
12
+ autoload :Reflection, 'formtastic/helpers/reflection'
13
+ autoload :Enum, 'formtastic/helpers/enum'
14
+ end
15
+ end
16
+
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ # @private
4
+ module HtmlAttributes
5
+ # Returns a namespace passed by option or inherited from parent builders / class configuration
6
+ def dom_id_namespace
7
+ namespace = options[:custom_namespace]
8
+ parent = options[:parent_builder]
9
+
10
+ case
11
+ when namespace then namespace
12
+ when parent && parent != self then parent.dom_id_namespace
13
+ else custom_namespace
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def humanized_attribute_name(method)
20
+ if @object && @object.class.respond_to?(:human_attribute_name)
21
+ humanized_name = @object.class.human_attribute_name(method.to_s)
22
+ if humanized_name == method.to_s.send(:humanize)
23
+ method.to_s.send(label_str_method)
24
+ else
25
+ humanized_name
26
+ end
27
+ else
28
+ method.to_s.send(label_str_method)
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Formtastic
4
+ # @private
5
+ module I18n
6
+
7
+ DEFAULT_SCOPE = [:formtastic].freeze
8
+ DEFAULT_VALUES = YAML.load_file(File.expand_path("../../locale/en.yml", __FILE__))["en"]["formtastic"].freeze
9
+ SCOPES = [
10
+ '%{model}.%{nested_model}.%{action}.%{attribute}',
11
+ '%{model}.%{nested_model}.%{attribute}',
12
+ '%{nested_model}.%{action}.%{attribute}',
13
+ '%{nested_model}.%{attribute}',
14
+ '%{model}.%{action}.%{attribute}',
15
+ '%{model}.%{attribute}',
16
+ '%{attribute}'
17
+ ]
18
+
19
+ class << self
20
+
21
+ def translate(*args)
22
+ key = args.shift.to_sym
23
+ options = args.extract_options!
24
+ options.reverse_merge!(:default => DEFAULT_VALUES[key])
25
+ options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
26
+ ::I18n.translate(key, *args, **options)
27
+ end
28
+ alias :t :translate
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+
4
+ # Uses the {Formtastic::NamespacedClassFinder} to look up input class names.
5
+ #
6
+ # See {Formtastic::FormBuilder#namespaced_input_class} for details.
7
+ #
8
+ class InputClassFinder < NamespacedClassFinder
9
+
10
+ # @param builder [FormBuilder]
11
+ def initialize(builder)
12
+ super builder.input_namespaces
13
+ end
14
+
15
+ def class_name(as)
16
+ "#{super}Input"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ module Inputs
4
+ module Base
5
+ module Aria
6
+
7
+ def error_aria_attributes
8
+ return {} unless builder.semantic_errors_link_to_inputs
9
+ return {} unless errors?
10
+
11
+ {
12
+ 'aria-describedby': describedby,
13
+ 'aria-invalid': options.dig(:input_html, :'aria-invalid') || 'true'
14
+ }
15
+ end
16
+
17
+ def describedby
18
+ describedby = options.dig(:input_html, :'aria-describedby') || ''
19
+ describedby += ' ' unless describedby.empty?
20
+ describedby += "#{method}_error"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Formtastic
3
+ module Inputs
4
+ module Base
5
+ module Associations
6
+ include Formtastic::Helpers::Reflection
7
+
8
+ # :belongs_to, etc
9
+ def association
10
+ @association ||= association_macro_for_method(method)
11
+ end
12
+
13
+ def reflection
14
+ @reflection ||= reflection_for(method)
15
+ end
16
+
17
+ def belongs_to?
18
+ association == :belongs_to
19
+ end
20
+
21
+ def has_many?
22
+ association == :has_many
23
+ end
24
+
25
+ def association_primary_key
26
+ association_primary_key_for_method(method)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end