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,11 @@
1
+ module Formtastic
2
+ # Required for formtastic.css to be discoverable in the asset pipeline
3
+ # @private
4
+ class Engine < ::Rails::Engine
5
+ initializer 'formtastic.initialize' do
6
+ ActiveSupport.on_load(:action_view) do
7
+ include Formtastic::Helpers::FormHelper
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,124 @@
1
+ module Formtastic
2
+ class FormBuilder < ActionView::Helpers::FormBuilder
3
+
4
+ # Defines a new configurable option
5
+ # @param [Symbol] name the configuration name
6
+ # @param [Object] default the configuration default value
7
+ # @private
8
+ #
9
+ # @!macro [new] configure
10
+ # @!scope class
11
+ # @!attribute [rw] $1
12
+ # @api public
13
+ def self.configure(name, default = nil)
14
+ class_attribute(name)
15
+ self.send(:"#{name}=", default)
16
+ end
17
+
18
+ configure :custom_namespace
19
+ configure :default_text_field_size
20
+ configure :default_text_area_height, 20
21
+ configure :default_text_area_width
22
+ configure :all_fields_required_by_default, true
23
+ configure :include_blank_for_select_by_default, true
24
+ configure :required_string, proc { Formtastic::Util.html_safe(%{<abbr title="#{Formtastic::I18n.t(:required)}">*</abbr>}) }
25
+ configure :optional_string, ''
26
+ configure :inline_errors, :sentence
27
+ configure :label_str_method, :humanize
28
+ configure :collection_label_methods, %w[to_label display_name full_name name title username login value to_s]
29
+ configure :collection_value_methods, %w[id to_s]
30
+ configure :file_methods, [ :file?, :public_filename, :filename ]
31
+ configure :file_metadata_suffixes, ['content_type', 'file_name', 'file_size']
32
+ configure :priority_countries, ["Australia", "Canada", "United Kingdom", "United States"]
33
+ configure :i18n_lookups_by_default, true
34
+ configure :i18n_cache_lookups, true
35
+ configure :i18n_localizer, Formtastic::Localizer
36
+ configure :escape_html_entities_in_hints_and_labels, true
37
+ configure :default_commit_button_accesskey
38
+ configure :default_inline_error_class, 'inline-errors'
39
+ configure :default_error_list_class, 'errors'
40
+ configure :default_hint_class, 'inline-hints'
41
+ configure :use_required_attribute, false
42
+ configure :perform_browser_validations, false
43
+ # Check {Formtastic::InputClassFinder} to see how are inputs resolved.
44
+ configure :input_namespaces, [::Object, ::Formtastic::Inputs]
45
+ # @todo enable this as default in 4.0 and remove it from configuration generator template
46
+ # Will be {Formtastic::InputClassFinder} by default in 4.0.
47
+ configure :input_class_finder #, Formtastic::InputClassFinder
48
+ # Check {Formtastic::ActionClassFinder} to see how are inputs resolved.
49
+ configure :action_namespaces, [::Object, ::Formtastic::Actions]
50
+ # @todo enable this as default in 4.0 and remove it from configuration generator template
51
+ # Will be {Formtastic::ActionClassFinder} by default in 4.0.
52
+ configure :action_class_finder#, Formtastic::ActionClassFinder
53
+
54
+ configure :skipped_columns, [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
55
+ configure :priority_time_zones, []
56
+
57
+ attr_reader :template
58
+
59
+ attr_reader :auto_index
60
+
61
+ include Formtastic::HtmlAttributes
62
+
63
+ include Formtastic::Helpers::InputHelper
64
+ include Formtastic::Helpers::InputsHelper
65
+ include Formtastic::Helpers::ActionHelper
66
+ include Formtastic::Helpers::ActionsHelper
67
+ include Formtastic::Helpers::ErrorsHelper
68
+
69
+ # This is a wrapper around Rails' `ActionView::Helpers::FormBuilder#fields_for`, originally
70
+ # provided to ensure that the `:builder` from `semantic_form_for` was passed down into
71
+ # the nested `fields_for`. Rails 3 no longer requires us to do this, so this method is
72
+ # provided purely for backwards compatibility and DSL consistency.
73
+ #
74
+ # When constructing a `fields_for` form fragment *outside* of `semantic_form_for`, please use
75
+ # `Formtastic::Helpers::FormHelper#semantic_fields_for`.
76
+ #
77
+ # @see http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-fields_for ActionView::Helpers::FormBuilder#fields_for
78
+ # @see http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for ActionView::Helpers::FormHelper#fields_for
79
+ # @see Formtastic::Helpers::FormHelper#semantic_fields_for
80
+ #
81
+ # @example
82
+ # <% semantic_form_for @post do |post| %>
83
+ # <% post.semantic_fields_for :author do |author| %>
84
+ # <% author.inputs :name %>
85
+ # <% end %>
86
+ # <% end %>
87
+ #
88
+ # <form ...>
89
+ # <fieldset class="inputs">
90
+ # <ol>
91
+ # <li class="string"><input type='text' name='post[author][name]' id='post_author_name' /></li>
92
+ # </ol>
93
+ # </fieldset>
94
+ # </form>
95
+ #
96
+ # @todo is there a way to test the params structure of the Rails helper we wrap to ensure forward compatibility?
97
+ def semantic_fields_for(record_or_name_or_array, *args, &block)
98
+ # Add a :parent_builder to the args so that nested translations can be possible in Rails 3
99
+ options = args.extract_options!
100
+ options[:parent_builder] ||= self
101
+
102
+ # Wrap the Rails helper
103
+ fields_for(record_or_name_or_array, *(args << options), &block)
104
+ end
105
+
106
+ def initialize(object_name, object, template, options, block=nil)
107
+ # rails 3 supported passing in the block parameter to FormBuilder
108
+ # rails 4.0 deprecated the block parameter and does nothing with it
109
+ # rails 4.1 removes the parameter completely
110
+ if Util.rails3? || Util.rails4_0?
111
+ super
112
+ else # Must be rails4_1 or greater
113
+ super object_name, object, template, options
114
+ end
115
+
116
+ if respond_to?('multipart=') && options.is_a?(Hash) && options[:html]
117
+ self.multipart = options[:html][:multipart]
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ end
124
+
@@ -0,0 +1,16 @@
1
+ module Formtastic
2
+ module Helpers
3
+ autoload :ButtonsHelper, 'formtastic/helpers/buttons_helper'
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,162 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Formtastic
3
+ module Helpers
4
+ module ActionHelper
5
+ ACTION_CLASS_DEPRECATION = 'configure Formtastic::FormBuilder.action_class_finder instead (upgrade guide on wiki: http://bit.ly/1F9QtKc )'.freeze
6
+ private_constant(:ACTION_CLASS_DEPRECATION)
7
+
8
+ # Renders an action for the form (such as a subit/reset button, or a cancel link).
9
+ #
10
+ # Each action is wrapped in an `<li class="action">` tag with other classes added based on the
11
+ # type of action being rendered, and is intended to be rendered inside a {#buttons}
12
+ # block which wraps the button in a `fieldset` and `ol`.
13
+ #
14
+ # The textual value of the label can be changed from the default through the `:label`
15
+ # argument or through i18n.
16
+ #
17
+ # If using i18n, you'll need to provide the following translations:
18
+ #
19
+ # en:
20
+ # formtastic:
21
+ # actions:
22
+ # create: "Create new %{model}"
23
+ # update: "Save %{model}"
24
+ # cancel: "Cancel"
25
+ # reset: "Reset form"
26
+ # submit: "Submit"
27
+ #
28
+ # For forms with an object present, the `update` key will be used if calling `persisted?` on
29
+ # the object returns true (saving changes to a record), otherwise the `create` key will be
30
+ # used. The `submit` key is used as a fallback when there is no object or we cannot determine
31
+ # if `create` or `update` is appropriate.
32
+ #
33
+ # @example Basic usage
34
+ # # form
35
+ # <%= semantic_form_for @post do |f| %>
36
+ # ...
37
+ # <%= f.actions do %>
38
+ # <%= f.action :submit %>
39
+ # <%= f.action :reset %>
40
+ # <%= f.action :cancel %>
41
+ # <% end %>
42
+ # <% end %>
43
+ #
44
+ # # output
45
+ # <form ...>
46
+ # ...
47
+ # <fieldset class="buttons">
48
+ # <ol>
49
+ # <li class="action input_action">
50
+ # <input name="commit" type="submit" value="Create Post">
51
+ # </li>
52
+ # <li class="action input_action">
53
+ # <input name="commit" type="reset" value="Reset Post">
54
+ # </li>
55
+ # <li class="action link_action">
56
+ # <a href="/posts">Cancel Post</a>
57
+ # </li>
58
+ # </ol>
59
+ # </fieldset>
60
+ # </form>
61
+ #
62
+ # @example Set the value through the `:label` option
63
+ # <%= f.action :submit, :label => "Go" %>
64
+ #
65
+ # @example Pass HTML attributes down to the tag inside the wrapper
66
+ # <%= f.action :submit, :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %>
67
+ #
68
+ # @example Pass HTML attributes down to the `<li>` wrapper
69
+ # <%= f.action :submit, :wrapper_html => { :class => 'special', :id => 'whatever' } %>
70
+ #
71
+ # @option *args :label [String, Symbol]
72
+ # Override the label text with a String or a symbold for an i18n translation key
73
+ #
74
+ # @option *args :button_html [Hash]
75
+ # Override or add to the HTML attributes to be passed down to the `<input>` tag
76
+ #
77
+ # @option *args :wrapper_html [Hash]
78
+ # Override or add to the HTML attributes to be passed down to the wrapping `<li>` tag
79
+ #
80
+ # @todo document i18n keys
81
+ def action(method, options = {})
82
+ options = options.dup # Allow options to be shared without being tainted by Formtastic
83
+ options[:as] ||= default_action_type(method, options)
84
+
85
+ klass = action_class(options[:as])
86
+
87
+ klass.new(self, template, @object, @object_name, method, options).to_html
88
+ end
89
+
90
+ protected
91
+
92
+ def default_action_type(method, options = {}) # @private
93
+ case method
94
+ when :submit then :input
95
+ when :reset then :input
96
+ when :cancel then :link
97
+ else method
98
+ end
99
+ end
100
+
101
+ # Takes the `:as` option and attempts to return the corresponding action
102
+ # class. In the case of `:as => :awesome` it will first attempt to find a
103
+ # top level `AwesomeAction` class (to allow the application to subclass
104
+ # and modify to suit), falling back to `Formtastic::Actions::AwesomeAction`.
105
+ #
106
+ # Custom action namespaces to look into can be configured via the
107
+ # {Formtastic::FormBuilder.action_namespaces} configuration setting.
108
+ # @see Helpers::InputHelper#namespaced_input_class
109
+ # @see Formtastic::ActionClassFinder
110
+ def namespaced_action_class(as)
111
+ @action_class_finder ||= action_class_finder.new(self)
112
+ @action_class_finder.find(as)
113
+ rescue Formtastic::ActionClassFinder::NotFoundError => e
114
+ raise Formtastic::UnknownActionError, "Unable to find action #{e.message}"
115
+ end
116
+
117
+ # @api private
118
+ # @deprecated Use {#namespaced_action_class} instead.
119
+ def action_class(as)
120
+ return namespaced_action_class(as) if action_class_finder
121
+
122
+ action_class_deprecation_warning(__method__)
123
+
124
+ @input_classes_cache ||= {}
125
+ @input_classes_cache[as] ||= begin
126
+ begin
127
+ begin
128
+ custom_action_class_name(as).constantize
129
+ rescue NameError
130
+ standard_action_class_name(as).constantize
131
+ end
132
+ rescue NameError
133
+ raise Formtastic::UnknownActionError, "Unable to find action #{as}"
134
+ end
135
+ end
136
+ end
137
+
138
+ # @api private
139
+ # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead.
140
+ # :as => :button # => ButtonAction
141
+ def custom_action_class_name(as)
142
+ action_class_deprecation_warning(__method__)
143
+ "#{as.to_s.camelize}Action"
144
+ end
145
+
146
+ # @api private
147
+ # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead.
148
+ # :as => :button # => Formtastic::Actions::ButtonAction
149
+ def standard_action_class_name(as)
150
+ action_class_deprecation_warning(__method__)
151
+ "Formtastic::Actions::#{as.to_s.camelize}Action"
152
+ end
153
+
154
+ private
155
+
156
+ def action_class_deprecation_warning(method)
157
+ @action_class_deprecation_warned ||=
158
+ Formtastic.deprecation.deprecation_warning(method, ACTION_CLASS_DEPRECATION, caller(2))
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,168 @@
1
+ module Formtastic
2
+ module Helpers
3
+ # ActionsHelper encapsulates the responsibilties of the {#actions} DSL for acting on
4
+ # (submitting, cancelling, resetting) forms.
5
+ #
6
+ # {#actions} is a block helper used to wrap the form's actions (buttons, links) in a
7
+ # `<fieldset>` and `<ol>`, with each item in the list containing the markup representing a
8
+ # single action.
9
+ #
10
+ # <%= semantic_form_for @post do |f| %>
11
+ # ...
12
+ # <%= f.actions do %>
13
+ # <%= f.action :submit
14
+ # <%= f.action :cancel
15
+ # <% end %>
16
+ # <% end %>
17
+ #
18
+ # The HTML output will be something like:
19
+ #
20
+ # <form class="formtastic" method="post" action="...">
21
+ # ...
22
+ # <fieldset class="actions">
23
+ # <ol>
24
+ # <li class="action input_action">
25
+ # <input type="submit" name="commit" value="Create Post">
26
+ # </li>
27
+ # <li class="action input_action">
28
+ # <a href="/posts">Cancel Post</a>
29
+ # </li>
30
+ # </ol>
31
+ # </fieldset>
32
+ # </form>
33
+ #
34
+ # It's important to note that the `semantic_form_for` and {#actions} blocks wrap the
35
+ # standard Rails `form_for` helper and form builder, so you have full access to every standard
36
+ # Rails form helper, with any HTML markup and ERB syntax, allowing you to "break free" from
37
+ # Formtastic when it doesn't suit to create your own buttons, links and actions:
38
+ #
39
+ # <%= semantic_form_for @post do |f| %>
40
+ # ...
41
+ # <%= f.actions do %>
42
+ # <li class="save">
43
+ # <%= f.submit "Save" %>
44
+ # <li>
45
+ # <li class="cancel-link">
46
+ # Or <%= link_to "Cancel", posts_url %>
47
+ # <li>
48
+ # <% end %>
49
+ # <% end %>
50
+ #
51
+ # There are many other syntax variations and arguments to customize your form. See the
52
+ # full documentation of {#actions} and {#action} for details.
53
+ module ActionsHelper
54
+
55
+ include Formtastic::Helpers::FieldsetWrapper
56
+
57
+ # Creates a fieldset and ol tag wrapping for use around a set of buttons. It can be
58
+ # called either with a block (in which you can do the usual Rails form stuff, HTML, ERB, etc),
59
+ # or with a list of named actions. These two examples are functionally equivalent:
60
+ #
61
+ # # With a block:
62
+ # <% semantic_form_for @post do |f| %>
63
+ # ...
64
+ # <% f.actions do %>
65
+ # <%= f.action :submit %>
66
+ # <%= f.action :cancel %>
67
+ # <% end %>
68
+ # <% end %>
69
+ #
70
+ # # With a list of fields:
71
+ # <% semantic_form_for @post do |f| %>
72
+ # <%= f.actions :submit, :cancel %>
73
+ # <% end %>
74
+ #
75
+ # # Output:
76
+ # <form ...>
77
+ # <fieldset class="buttons">
78
+ # <ol>
79
+ # <li class="action input_action">
80
+ # <input type="submit" ...>
81
+ # </li>
82
+ # <li class="action link_action">
83
+ # <a href="...">...</a>
84
+ # </li>
85
+ # </ol>
86
+ # </fieldset>
87
+ # </form>
88
+ #
89
+ # All options except `:name` and `:title` are passed down to the fieldset as HTML
90
+ # attributes (`id`, `class`, `style`...). If provided, the `:name` or `:title` option is
91
+ # passed into a `<legend>` inside the `<fieldset>` to name the set of buttons.
92
+ #
93
+ # @example Quickly add button(s) to the form, accepting all default values, options and behaviors
94
+ # <% semantic_form_for @post do |f| %>
95
+ # ...
96
+ # <%= f.actions %>
97
+ # <% end %>
98
+ #
99
+ # @example Specify which named buttons you want, accepting all default values, options and behaviors
100
+ # <% semantic_form_for @post do |f| %>
101
+ # ...
102
+ # <%= f.actions :commit %>
103
+ # <% end %>
104
+ #
105
+ # @example Specify which named buttons you want, and name the fieldset
106
+ # <% semantic_form_for @post do |f| %>
107
+ # ...
108
+ # <%= f.actions :commit, :name => "Actions" %>
109
+ # or
110
+ # <%= f.actions :commit, :label => "Actions" %>
111
+ # <% end %>
112
+ #
113
+ # @example Get full control over the action options
114
+ # <% semantic_form_for @post do |f| %>
115
+ # ...
116
+ # <%= f.actions do %>
117
+ # <%= f.action :label => "Go", :button_html => { :class => "pretty" :disable_with => "Wait..." }, :wrapper_html => { ... }
118
+ # <% end %>
119
+ # <% end %>
120
+ #
121
+ # @example Make your own actions with standard Rails helpers or HTML
122
+ # <% semantic_form_for @post do |f| %>
123
+ # <%= f.actions do %>
124
+ # <li>
125
+ # ...
126
+ # </li>
127
+ # <% end %>
128
+ # <% end %>
129
+ #
130
+ # @example Add HTML attributes to the fieldset
131
+ # <% semantic_form_for @post do |f| %>
132
+ # ...
133
+ # <%= f.actions :commit, :style => "border:1px;" %>
134
+ # or
135
+ # <%= f.actions :style => "border:1px;" do %>
136
+ # ...
137
+ # <% end %>
138
+ # <% end %>
139
+ #
140
+ # @option *args :label [String, Symbol]
141
+ # Optionally specify text for the legend of the fieldset
142
+ #
143
+ # @option *args :name [String, Symbol]
144
+ # Optionally specify text for the legend of the fieldset (alias for `:label`)
145
+ #
146
+ # @todo document i18n keys
147
+ def actions(*args, &block)
148
+ html_options = args.extract_options!
149
+ html_options[:class] ||= "actions"
150
+
151
+ if block_given?
152
+ field_set_and_list_wrapping(html_options, &block)
153
+ else
154
+ args = default_actions if args.empty?
155
+ contents = args.map { |action_name| action(action_name) }
156
+ field_set_and_list_wrapping(html_options, contents)
157
+ end
158
+ end
159
+
160
+ protected
161
+
162
+ def default_actions
163
+ [:submit]
164
+ end
165
+
166
+ end
167
+ end
168
+ end