formtastic 1.2.4 → 3.1.5

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 (189) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +46 -0
  5. data/.yardopts +1 -0
  6. data/Appraisals +43 -0
  7. data/CHANGELOG +54 -0
  8. data/DEPRECATIONS +52 -0
  9. data/Gemfile +3 -0
  10. data/README.md +629 -0
  11. data/RELEASE_PROCESS +6 -0
  12. data/Rakefile +35 -0
  13. data/app/assets/stylesheets/formtastic.css +289 -0
  14. data/app/assets/stylesheets/formtastic_ie6.css +33 -0
  15. data/app/assets/stylesheets/formtastic_ie7.css +23 -0
  16. data/formtastic.gemspec +42 -0
  17. data/gemfiles/rails_3.2.gemfile +9 -0
  18. data/gemfiles/rails_4.0.4.gemfile +8 -0
  19. data/gemfiles/rails_4.1.gemfile +8 -0
  20. data/gemfiles/rails_4.2.gemfile +8 -0
  21. data/gemfiles/rails_4.gemfile +8 -0
  22. data/gemfiles/rails_5.0.gemfile +8 -0
  23. data/gemfiles/rails_edge.gemfile +15 -0
  24. data/lib/formtastic.rb +40 -1945
  25. data/lib/formtastic/action_class_finder.rb +18 -0
  26. data/lib/formtastic/actions.rb +11 -0
  27. data/lib/formtastic/actions/base.rb +156 -0
  28. data/lib/formtastic/actions/button_action.rb +67 -0
  29. data/lib/formtastic/actions/buttonish.rb +17 -0
  30. data/lib/formtastic/actions/input_action.rb +70 -0
  31. data/lib/formtastic/actions/link_action.rb +88 -0
  32. data/lib/formtastic/deprecation.rb +42 -0
  33. data/lib/formtastic/engine.rb +11 -0
  34. data/lib/formtastic/form_builder.rb +124 -0
  35. data/lib/formtastic/helpers.rb +16 -0
  36. data/lib/formtastic/helpers/action_helper.rb +162 -0
  37. data/lib/formtastic/helpers/actions_helper.rb +168 -0
  38. data/lib/formtastic/helpers/enum.rb +13 -0
  39. data/lib/formtastic/helpers/errors_helper.rb +81 -0
  40. data/lib/formtastic/helpers/fieldset_wrapper.rb +80 -0
  41. data/lib/formtastic/helpers/file_column_detection.rb +16 -0
  42. data/lib/formtastic/helpers/form_helper.rb +203 -0
  43. data/lib/formtastic/helpers/input_helper.rb +407 -0
  44. data/lib/formtastic/helpers/inputs_helper.rb +411 -0
  45. data/lib/formtastic/helpers/reflection.rb +37 -0
  46. data/lib/formtastic/html_attributes.rb +32 -0
  47. data/lib/formtastic/i18n.rb +4 -2
  48. data/lib/formtastic/input_class_finder.rb +18 -0
  49. data/lib/formtastic/inputs.rb +39 -0
  50. data/lib/formtastic/inputs/base.rb +76 -0
  51. data/lib/formtastic/inputs/base/associations.rb +31 -0
  52. data/lib/formtastic/inputs/base/choices.rb +108 -0
  53. data/lib/formtastic/inputs/base/collections.rb +159 -0
  54. data/lib/formtastic/inputs/base/database.rb +22 -0
  55. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  56. data/lib/formtastic/inputs/base/errors.rb +58 -0
  57. data/lib/formtastic/inputs/base/fileish.rb +23 -0
  58. data/lib/formtastic/inputs/base/hints.rb +31 -0
  59. data/lib/formtastic/inputs/base/html.rb +53 -0
  60. data/lib/formtastic/inputs/base/labelling.rb +52 -0
  61. data/lib/formtastic/inputs/base/naming.rb +42 -0
  62. data/lib/formtastic/inputs/base/numeric.rb +50 -0
  63. data/lib/formtastic/inputs/base/options.rb +17 -0
  64. data/lib/formtastic/inputs/base/placeholder.rb +17 -0
  65. data/lib/formtastic/inputs/base/stringish.rb +38 -0
  66. data/lib/formtastic/inputs/base/timeish.rb +241 -0
  67. data/lib/formtastic/inputs/base/validations.rb +215 -0
  68. data/lib/formtastic/inputs/base/wrapping.rb +50 -0
  69. data/lib/formtastic/inputs/boolean_input.rb +118 -0
  70. data/lib/formtastic/inputs/check_boxes_input.rb +197 -0
  71. data/lib/formtastic/inputs/color_input.rb +42 -0
  72. data/lib/formtastic/inputs/country_input.rb +86 -0
  73. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  74. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  75. data/lib/formtastic/inputs/date_select_input.rb +34 -0
  76. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  77. data/lib/formtastic/inputs/datetime_select_input.rb +12 -0
  78. data/lib/formtastic/inputs/email_input.rb +41 -0
  79. data/lib/formtastic/inputs/file_input.rb +42 -0
  80. data/lib/formtastic/inputs/hidden_input.rb +62 -0
  81. data/lib/formtastic/inputs/number_input.rb +88 -0
  82. data/lib/formtastic/inputs/password_input.rb +41 -0
  83. data/lib/formtastic/inputs/phone_input.rb +42 -0
  84. data/lib/formtastic/inputs/radio_input.rb +163 -0
  85. data/lib/formtastic/inputs/range_input.rb +95 -0
  86. data/lib/formtastic/inputs/search_input.rb +41 -0
  87. data/lib/formtastic/inputs/select_input.rb +235 -0
  88. data/lib/formtastic/inputs/string_input.rb +36 -0
  89. data/lib/formtastic/inputs/text_input.rb +48 -0
  90. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  91. data/lib/formtastic/inputs/time_select_input.rb +38 -0
  92. data/lib/formtastic/inputs/time_zone_input.rb +58 -0
  93. data/lib/formtastic/inputs/url_input.rb +41 -0
  94. data/lib/formtastic/localized_string.rb +17 -0
  95. data/lib/formtastic/localizer.rb +152 -0
  96. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  97. data/lib/formtastic/util.rb +35 -16
  98. data/lib/formtastic/version.rb +3 -0
  99. data/lib/generators/formtastic/form/form_generator.rb +64 -37
  100. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  101. data/lib/generators/formtastic/install/install_generator.rb +13 -5
  102. data/lib/generators/templates/_form.html.erb +10 -4
  103. data/lib/generators/templates/_form.html.haml +8 -4
  104. data/lib/generators/templates/_form.html.slim +8 -0
  105. data/lib/generators/templates/formtastic.rb +77 -44
  106. data/lib/generators/templates/input.rb +19 -0
  107. data/lib/locale/en.yml +3 -0
  108. data/sample/basic_inputs.html +224 -0
  109. data/sample/config.ru +69 -0
  110. data/sample/index.html +14 -0
  111. data/spec/action_class_finder_spec.rb +12 -0
  112. data/spec/actions/button_action_spec.rb +63 -0
  113. data/spec/actions/generic_action_spec.rb +521 -0
  114. data/spec/actions/input_action_spec.rb +59 -0
  115. data/spec/actions/link_action_spec.rb +92 -0
  116. data/spec/builder/custom_builder_spec.rb +116 -0
  117. data/spec/builder/error_proc_spec.rb +27 -0
  118. data/spec/builder/semantic_fields_for_spec.rb +142 -0
  119. data/spec/fast_spec_helper.rb +12 -0
  120. data/spec/generators/formtastic/form/form_generator_spec.rb +131 -0
  121. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  122. data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
  123. data/spec/helpers/action_helper_spec.rb +19 -0
  124. data/spec/helpers/actions_helper_spec.rb +143 -0
  125. data/spec/helpers/form_helper_spec.rb +218 -0
  126. data/spec/helpers/input_helper_spec.rb +6 -0
  127. data/spec/helpers/inputs_helper_spec.rb +655 -0
  128. data/spec/helpers/namespaced_action_helper_spec.rb +43 -0
  129. data/spec/helpers/namespaced_input_helper_spec.rb +36 -0
  130. data/spec/helpers/reflection_helper_spec.rb +32 -0
  131. data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
  132. data/spec/i18n_spec.rb +210 -0
  133. data/spec/input_class_finder_spec.rb +10 -0
  134. data/spec/inputs/base/collections_spec.rb +76 -0
  135. data/spec/inputs/base/validations_spec.rb +342 -0
  136. data/spec/inputs/boolean_input_spec.rb +254 -0
  137. data/spec/inputs/check_boxes_input_spec.rb +546 -0
  138. data/spec/inputs/color_input_spec.rb +97 -0
  139. data/spec/inputs/country_input_spec.rb +133 -0
  140. data/spec/inputs/custom_input_spec.rb +55 -0
  141. data/spec/inputs/datalist_input_spec.rb +61 -0
  142. data/spec/inputs/date_picker_input_spec.rb +449 -0
  143. data/spec/inputs/date_select_input_spec.rb +235 -0
  144. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  145. data/spec/inputs/datetime_select_input_spec.rb +193 -0
  146. data/spec/inputs/email_input_spec.rb +85 -0
  147. data/spec/inputs/file_input_spec.rb +89 -0
  148. data/spec/inputs/hidden_input_spec.rb +135 -0
  149. data/spec/inputs/include_blank_spec.rb +78 -0
  150. data/spec/inputs/label_spec.rb +149 -0
  151. data/spec/inputs/number_input_spec.rb +815 -0
  152. data/spec/inputs/password_input_spec.rb +99 -0
  153. data/spec/inputs/phone_input_spec.rb +85 -0
  154. data/spec/inputs/placeholder_spec.rb +71 -0
  155. data/spec/inputs/radio_input_spec.rb +328 -0
  156. data/spec/inputs/range_input_spec.rb +505 -0
  157. data/spec/inputs/readonly_spec.rb +50 -0
  158. data/spec/inputs/search_input_spec.rb +84 -0
  159. data/spec/inputs/select_input_spec.rb +615 -0
  160. data/spec/inputs/string_input_spec.rb +260 -0
  161. data/spec/inputs/text_input_spec.rb +187 -0
  162. data/spec/inputs/time_picker_input_spec.rb +455 -0
  163. data/spec/inputs/time_select_input_spec.rb +248 -0
  164. data/spec/inputs/time_zone_input_spec.rb +143 -0
  165. data/spec/inputs/url_input_spec.rb +85 -0
  166. data/spec/inputs/with_options_spec.rb +43 -0
  167. data/spec/localizer_spec.rb +130 -0
  168. data/spec/namespaced_class_finder_spec.rb +79 -0
  169. data/spec/spec.opts +2 -0
  170. data/spec/spec_helper.rb +525 -0
  171. data/spec/support/custom_macros.rb +564 -0
  172. data/spec/support/deprecation.rb +6 -0
  173. data/spec/support/shared_examples.rb +1313 -0
  174. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  175. data/spec/support/test_environment.rb +31 -0
  176. data/spec/util_spec.rb +66 -0
  177. metadata +434 -161
  178. data/README.textile +0 -682
  179. data/generators/form/USAGE +0 -16
  180. data/generators/form/form_generator.rb +0 -111
  181. data/generators/formtastic/formtastic_generator.rb +0 -26
  182. data/init.rb +0 -5
  183. data/lib/formtastic/layout_helper.rb +0 -12
  184. data/lib/formtastic/railtie.rb +0 -14
  185. data/lib/generators/templates/formtastic.css +0 -145
  186. data/lib/generators/templates/formtastic_changes.css +0 -14
  187. data/lib/generators/templates/rails2/_form.html.erb +0 -5
  188. data/lib/generators/templates/rails2/_form.html.haml +0 -4
  189. data/rails/init.rb +0 -2
@@ -0,0 +1,18 @@
1
+ module Formtastic
2
+
3
+ # Uses the {NamespacedClassFinder} to look up action class names.
4
+ #
5
+ # See {Formtastic::Helpers::ActionHelper#namespaced_action_class} for details.
6
+ #
7
+ class ActionClassFinder < NamespacedClassFinder
8
+
9
+ # @param builder [FormBuilder]
10
+ def initialize(builder)
11
+ super builder.action_namespaces
12
+ end
13
+
14
+ def class_name(as)
15
+ "#{super}Action"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Formtastic
2
+ module Actions
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Base
6
+ autoload :Buttonish
7
+ autoload :InputAction
8
+ autoload :LinkAction
9
+ autoload :ButtonAction
10
+ end
11
+ end
@@ -0,0 +1,156 @@
1
+ module Formtastic
2
+ module Actions
3
+ module Base
4
+ include Formtastic::LocalizedString
5
+
6
+ attr_accessor :builder, :template, :object, :object_name, :method, :options
7
+
8
+ def initialize(builder, template, object, object_name, method, options)
9
+ @builder = builder
10
+ @template = template
11
+ @object = object
12
+ @object_name = object_name
13
+ @method = method
14
+ @options = options.dup
15
+
16
+ check_supported_methods!
17
+ end
18
+
19
+ def to_html
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def wrapper(&block)
24
+ template.content_tag(:li,
25
+ template.capture(&block),
26
+ wrapper_html_options
27
+ )
28
+ end
29
+
30
+ def wrapper_html_options
31
+ wrapper_html_options_from_options.merge(default_wrapper_html_options)
32
+ end
33
+
34
+ def wrapper_html_options_from_options
35
+ options[:wrapper_html] || {}
36
+ end
37
+
38
+ def default_wrapper_html_options
39
+ {
40
+ :class => wrapper_class,
41
+ :id => wrapper_id
42
+ }
43
+ end
44
+
45
+ def wrapper_class
46
+ (default_wrapper_classes << wrapper_classes_from_options).join(" ")
47
+ end
48
+
49
+ def default_wrapper_classes
50
+ ["action", "#{options[:as]}_action"]
51
+ end
52
+
53
+ def wrapper_classes_from_options
54
+ classes = wrapper_html_options_from_options[:class] || []
55
+ classes = classes.split(" ") if classes.is_a? String
56
+ classes
57
+ end
58
+
59
+ def wrapper_html_options_from_options
60
+ options[:wrapper_html] || {}
61
+ end
62
+
63
+ def wrapper_id
64
+ wrapper_id_from_options || default_wrapper_id
65
+ end
66
+
67
+ def wrapper_id_from_options
68
+ wrapper_html_options_from_options[:id]
69
+ end
70
+
71
+ def default_wrapper_id
72
+ "#{object_name}_#{method}_action"
73
+ end
74
+
75
+ def supported_methods
76
+ raise NotImplementedError
77
+ end
78
+
79
+ def text
80
+ text = options[:label]
81
+ text = (localized_string(i18n_key, text, :action, :model => sanitized_object_name) ||
82
+ Formtastic::I18n.t(i18n_key, :model => sanitized_object_name)) unless text.is_a?(::String)
83
+ text
84
+ end
85
+
86
+ def button_html
87
+ default_button_html.merge(button_html_from_options || {}).merge(extra_button_html_options)
88
+ end
89
+
90
+ def button_html_from_options
91
+ options[:button_html]
92
+ end
93
+
94
+ def extra_button_html_options
95
+ {}
96
+ end
97
+
98
+ def default_button_html
99
+ { :accesskey => accesskey }
100
+ end
101
+
102
+ def accesskey
103
+ # TODO could be cleaner and separated, remember that nil is an allowed value for all of these
104
+ return options[:accesskey] if options.key?(:accesskey)
105
+ return options[:button_html][:accesskey] if options.key?(:button_html) && options[:button_html].key?(:accesskey)
106
+ # TODO might be different for cancel, etc?
107
+ return builder.default_commit_button_accesskey
108
+ end
109
+
110
+
111
+ protected
112
+
113
+ def check_supported_methods!
114
+ raise Formtastic::UnsupportedMethodForAction unless supported_methods.include?(method)
115
+ end
116
+
117
+ def i18n_key
118
+ return submit_i18n_key if method == :submit
119
+ method
120
+ end
121
+
122
+ def submit_i18n_key
123
+ if new_or_persisted_object?
124
+ key = @object.persisted? ? :update : :create
125
+ else
126
+ key = :submit
127
+ end
128
+ end
129
+
130
+ def new_or_persisted_object?
131
+ object && (object.respond_to?(:persisted?) || object.respond_to?(:new_record?))
132
+ end
133
+
134
+ def sanitized_object_name
135
+ if new_or_persisted_object?
136
+ # Deal with some complications with ActiveRecord::Base.human_name and two name models (eg UserPost)
137
+ # ActiveRecord::Base.human_name falls back to ActiveRecord::Base.name.humanize ("Userpost")
138
+ # if there's no i18n, which is pretty crappy. In this circumstance we want to detect this
139
+ # fall back (human_name == name.humanize) and do our own thing name.underscore.humanize ("User Post")
140
+ if object.class.model_name.respond_to?(:human)
141
+ sanitized_object_name = object.class.model_name.human
142
+ else
143
+ object_human_name = @object.class.human_name # default is UserPost => "Userpost", but i18n may do better ("User post")
144
+ crappy_human_name = @object.class.name.humanize # UserPost => "Userpost"
145
+ decent_human_name = @object.class.name.underscore.humanize # UserPost => "User post"
146
+ sanitized_object_name = (object_human_name == crappy_human_name) ? decent_human_name : object_human_name
147
+ end
148
+ else
149
+ sanitized_object_name = object_name.to_s.send(builder.label_str_method)
150
+ end
151
+ sanitized_object_name
152
+ end
153
+
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,67 @@
1
+ module Formtastic
2
+ module Actions
3
+
4
+ # Outputs a `<button type="submit">` or `<button type="reset">` wrapped in the standard `<li>`
5
+ # wrapper. This is an alternative choice for `:submit` and `:reset` actions, which render with
6
+ # `<input type="submit">` and `<input type="reset">` by default.
7
+ #
8
+ # @example Full form context and output
9
+ #
10
+ # <%= semantic_form_for(@post) do |f| %>
11
+ # <%= f.actions do %>
12
+ # <%= f.action :reset, :as => :button %>
13
+ # <%= f.action :submit, :as => :button %>
14
+ # <% end %>
15
+ # <% end %>
16
+ #
17
+ # <form...>
18
+ # <fieldset class="actions">
19
+ # <ol>
20
+ # <li class="action button_action" id="post_reset_action">
21
+ # <button type="reset" value="Reset">
22
+ # </li>
23
+ # <li class="action button_action" id="post_submit_action">
24
+ # <button type="submit" value="Create Post">
25
+ # </li>
26
+ # </ol>
27
+ # </fieldset>
28
+ # </form>
29
+ #
30
+ # @example Specifying a label with a String
31
+ # <%= f.action :submit, :as => :button, :label => "Go" %>
32
+ #
33
+ # @example Pass HTML attributes down to the `<button>`
34
+ # <%= f.action :submit, :as => :button, :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
35
+ #
36
+ # @example Access key can also be set as a top-level option
37
+ # <%= f.action :submit, :as => :button, :accesskey => 'g' %>
38
+ #
39
+ # @example Pass HTML attributes down to the `<li>` wrapper (classes are appended to the existing classes)
40
+ # <%= f.action :submit, :as => :button, :wrapper_html => { :class => 'special', :id => 'whatever' } %>
41
+ # <%= f.action :submit, :as => :button, :wrapper_html => { :class => ['extra', 'special'], :id => 'whatever' } %>
42
+ #
43
+ # @todo document i18n keys
44
+ # @todo document i18n translation with :label (?)
45
+ class ButtonAction
46
+ include Base
47
+ include Buttonish
48
+
49
+ # @see Formtastic::Helpers::ActionHelper#action
50
+ # @option *args :label [String, Symbol]
51
+ # Override the label text with a String or a symbol for an i18n translation key
52
+ #
53
+ # @option *args :button_html [Hash]
54
+ # Override or add to the HTML attributes to be passed down to the `<input>` tag
55
+ #
56
+ # @option *args :wrapper_html [Hash]
57
+ # Override or add to the HTML attributes to be passed down to the wrapping `<li>` tag
58
+
59
+ # TODO reset_action class?
60
+ def to_html
61
+ wrapper do
62
+ template.button_tag(text, button_html)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,17 @@
1
+ module Formtastic
2
+ module Actions
3
+ module Buttonish
4
+
5
+ def supported_methods
6
+ [:submit, :reset]
7
+ end
8
+
9
+ def extra_button_html_options
10
+ {
11
+ :type => method
12
+ }
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,70 @@
1
+ module Formtastic
2
+ module Actions
3
+
4
+ # Outputs an `<input type="submit">` or `<input type="reset">` wrapped in the standard `<li>`
5
+ # wrapper. This the default for `:submit` and `:reset` actions, but `:as => :button` is also
6
+ # available as an alternative.
7
+ #
8
+ # @example The `:as` can be ommitted, these are functionally equivalent
9
+ # <%= f.action :submit, :as => :input %>
10
+ # <%= f.action :submit %>
11
+ #
12
+ # @example Full form context and output
13
+ #
14
+ # <%= semantic_form_for(@post) do |f| %>
15
+ # <%= f.actions do %>
16
+ # <%= f.action :reset, :as => :input %>
17
+ # <%= f.action :submit, :as => :input %>
18
+ # <% end %>
19
+ # <% end %>
20
+ #
21
+ # <form...>
22
+ # <fieldset class="actions">
23
+ # <ol>
24
+ # <li class="action input_action" id="post_reset_action">
25
+ # <input type="reset" value="Reset">
26
+ # </li>
27
+ # <li class="action input_action" id="post_submit_action">
28
+ # <input type="submit" value="Create Post">
29
+ # </li>
30
+ # </ol>
31
+ # </fieldset>
32
+ # </form>
33
+ #
34
+ # @example Specifying a label with a String
35
+ # <%= f.action :submit, :as => :input, :label => "Go" %>
36
+ #
37
+ # @example Pass HTML attributes down to the `<input>`
38
+ # <%= f.action :submit, :as => :input, :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
39
+ #
40
+ # @example Access key can also be set as a top-level option
41
+ # <%= f.action :submit, :as => :input, :accesskey => 'g' %>
42
+ #
43
+ # @example Pass HTML attributes down to the `<li>` wrapper (classes are appended to the existing classes)
44
+ # <%= f.action :submit, :as => :input, :wrapper_html => { :class => 'special', :id => 'whatever' } %>
45
+ # <%= f.action :submit, :as => :input, :wrapper_html => { :class => ['extra', 'special'], :id => 'whatever' } %>
46
+ # @todo document i18n keys
47
+ # @todo document i18n translation with :label (?)
48
+ class InputAction
49
+ include Base
50
+ include Buttonish
51
+
52
+ # @see Formtastic::Helpers::ActionHelper#action
53
+ # @option *args :label [String, Symbol]
54
+ # Override the label text with a String or a symbol for an i18n translation key
55
+ #
56
+ # @option *args :button_html [Hash]
57
+ # Override or add to the HTML attributes to be passed down to the `<input>` tag
58
+ #
59
+ # @option *args :wrapper_html [Hash]
60
+ # Override or add to the HTML attributes to be passed down to the wrapping `<li>` tag
61
+ #
62
+
63
+ def to_html
64
+ wrapper do
65
+ builder.submit(text, button_html)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,88 @@
1
+ module Formtastic
2
+ module Actions
3
+ # Outputs a link wrapped in the standard `<li>` wrapper. This the default for `:cancel` actions.
4
+ # The link's URL defaults to Rails' built-in `:back` macro (the HTTP referrer, or Javascript for the
5
+ # browser's history), but can be altered with the `:url` option.
6
+ #
7
+ # @example The `:as` can be ommitted, these are functionally equivalent
8
+ # <%= f.action :cancel, :as => :link %>
9
+ # <%= f.action :cancel %>
10
+ #
11
+ # @example Full form context and output
12
+ #
13
+ # <%= semantic_form_for(@post) do |f| %>
14
+ # <%= f.actions do %>
15
+ # <%= f.action :submit, :as => :input %>
16
+ # <%= f.action :cancel, :as => :link %>
17
+ # <% end %>
18
+ # <% end %>
19
+ #
20
+ # <form...>
21
+ # <fieldset class="actions">
22
+ # <ol>
23
+ # <li class="action input_action" id="post_submit_action">
24
+ # <input type="submit" value="Create Post">
25
+ # </li>
26
+ # <li class="action link_action" id="post_cancel_action">
27
+ # <a href="javascript:history.back()">Cancel</a>
28
+ # </li>
29
+ # </ol>
30
+ # </fieldset>
31
+ # </form>
32
+ #
33
+ # @example Modifying the URL for the link
34
+ # <%= f.action :cancel, :as => :link, :url => "http://example.com/path" %>
35
+ # <%= f.action :cancel, :as => :link, :url => "/path" %>
36
+ # <%= f.action :cancel, :as => :link, :url => posts_path %>
37
+ # <%= f.action :cancel, :as => :link, :url => url_for(...) %>
38
+ # <%= f.action :cancel, :as => :link, :url => { :controller => "posts", :action => "index" } %>
39
+ #
40
+ # @example Specifying a label with a String
41
+ # <%= f.action :cancel, :as => :link, :label => "Stop" %>
42
+ #
43
+ # @example Pass HTML attributes down to the `<a>`
44
+ # <%= f.action :cancel, :as => :link, :button_html => { :class => 'pretty', :accesskey => 'x' } %>
45
+ #
46
+ # @example Access key can also be set as a top-level option
47
+ # <%= f.action :cancel, :as => :link, :accesskey => 'x' %>
48
+ #
49
+ # @example Pass HTML attributes down to the `<li>` wrapper (classes are appended to the existing classes)
50
+ # <%= f.action :cancel, :as => :link, :wrapper_html => { :class => 'special', :id => 'whatever' } %>
51
+ # <%= f.action :cancel, :as => :link, :wrapper_html => { :class => ['extra', 'special'], :id => 'whatever' } %>
52
+ #
53
+ # @todo document i18n keys
54
+ # @todo document i18n translation with :label (?)
55
+ # @todo :prefix and :suffix options? (can also be done with CSS or subclassing for custom Actions)
56
+ class LinkAction
57
+ include Base
58
+
59
+ # @see Formtastic::Helpers::ActionHelper#action
60
+ # @option *args :label [String, Symbol]
61
+ # Override the label text with a String or a symbol for an i18n translation key
62
+ #
63
+ # @option *args :button_html [Hash]
64
+ # Override or add to the HTML attributes to be passed down to the `<a>` tag
65
+ #
66
+ # @option *args :wrapper_html [Hash]
67
+ # Override or add to the HTML attributes to be passed down to the wrapping `<li>` tag
68
+ #
69
+
70
+ def supported_methods
71
+ [:cancel]
72
+ end
73
+
74
+ # TODO reset_action class?
75
+ def to_html
76
+ wrapper do
77
+ template.link_to(text, url, button_html)
78
+ end
79
+ end
80
+
81
+ def url
82
+ return options[:url] if options.key?(:url)
83
+ :back
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_support/deprecation'
2
+
3
+ module Formtastic
4
+ if ActiveSupport::Deprecation.respond_to?(:new)
5
+ Deprecation = ActiveSupport::Deprecation
6
+ else
7
+ require 'forwardable'
8
+
9
+ # @private
10
+ # @todo remove this branch and file when support for rails 3.2 is dropped
11
+ class Deprecation
12
+ mattr_accessor :deprecation
13
+ self.deprecation = ActiveSupport::Deprecation.dup
14
+
15
+ extend Forwardable
16
+ methods = deprecation.methods - deprecation.class.methods
17
+ def_delegators :deprecation, *methods
18
+
19
+ def initialize(version, _library)
20
+ deprecation.silenced = false
21
+ deprecation.deprecation_horizon = version
22
+ end
23
+
24
+ def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)
25
+ caller_backtrace ||= caller(2)
26
+
27
+ deprecated_method_warning(deprecated_method_name, message).tap do |msg|
28
+ warn(msg, caller_backtrace)
29
+ end
30
+ end
31
+
32
+ def deprecated_method_warning(method_name, message = nil)
33
+ warning = "#{method_name} is deprecated and will be removed from Formtastic #{deprecation_horizon}"
34
+ case message
35
+ when Symbol then "#{warning} (use #{message} instead)"
36
+ when String then "#{warning} (#{message})"
37
+ else warning
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end