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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +46 -0
- data/.yardopts +1 -0
- data/Appraisals +43 -0
- data/CHANGELOG +54 -0
- data/DEPRECATIONS +52 -0
- data/Gemfile +3 -0
- data/README.md +629 -0
- data/RELEASE_PROCESS +6 -0
- data/Rakefile +35 -0
- data/app/assets/stylesheets/formtastic.css +289 -0
- data/app/assets/stylesheets/formtastic_ie6.css +33 -0
- data/app/assets/stylesheets/formtastic_ie7.css +23 -0
- data/formtastic.gemspec +42 -0
- data/gemfiles/rails_3.2.gemfile +9 -0
- data/gemfiles/rails_4.0.4.gemfile +8 -0
- data/gemfiles/rails_4.1.gemfile +8 -0
- data/gemfiles/rails_4.2.gemfile +8 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/gemfiles/rails_5.0.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile +15 -0
- data/lib/formtastic.rb +40 -1945
- data/lib/formtastic/action_class_finder.rb +18 -0
- data/lib/formtastic/actions.rb +11 -0
- data/lib/formtastic/actions/base.rb +156 -0
- data/lib/formtastic/actions/button_action.rb +67 -0
- data/lib/formtastic/actions/buttonish.rb +17 -0
- data/lib/formtastic/actions/input_action.rb +70 -0
- data/lib/formtastic/actions/link_action.rb +88 -0
- data/lib/formtastic/deprecation.rb +42 -0
- data/lib/formtastic/engine.rb +11 -0
- data/lib/formtastic/form_builder.rb +124 -0
- data/lib/formtastic/helpers.rb +16 -0
- data/lib/formtastic/helpers/action_helper.rb +162 -0
- data/lib/formtastic/helpers/actions_helper.rb +168 -0
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +81 -0
- data/lib/formtastic/helpers/fieldset_wrapper.rb +80 -0
- data/lib/formtastic/helpers/file_column_detection.rb +16 -0
- data/lib/formtastic/helpers/form_helper.rb +203 -0
- data/lib/formtastic/helpers/input_helper.rb +407 -0
- data/lib/formtastic/helpers/inputs_helper.rb +411 -0
- data/lib/formtastic/helpers/reflection.rb +37 -0
- data/lib/formtastic/html_attributes.rb +32 -0
- data/lib/formtastic/i18n.rb +4 -2
- data/lib/formtastic/input_class_finder.rb +18 -0
- data/lib/formtastic/inputs.rb +39 -0
- data/lib/formtastic/inputs/base.rb +76 -0
- data/lib/formtastic/inputs/base/associations.rb +31 -0
- data/lib/formtastic/inputs/base/choices.rb +108 -0
- data/lib/formtastic/inputs/base/collections.rb +159 -0
- data/lib/formtastic/inputs/base/database.rb +22 -0
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
- data/lib/formtastic/inputs/base/errors.rb +58 -0
- data/lib/formtastic/inputs/base/fileish.rb +23 -0
- data/lib/formtastic/inputs/base/hints.rb +31 -0
- data/lib/formtastic/inputs/base/html.rb +53 -0
- data/lib/formtastic/inputs/base/labelling.rb +52 -0
- data/lib/formtastic/inputs/base/naming.rb +42 -0
- data/lib/formtastic/inputs/base/numeric.rb +50 -0
- data/lib/formtastic/inputs/base/options.rb +17 -0
- data/lib/formtastic/inputs/base/placeholder.rb +17 -0
- data/lib/formtastic/inputs/base/stringish.rb +38 -0
- data/lib/formtastic/inputs/base/timeish.rb +241 -0
- data/lib/formtastic/inputs/base/validations.rb +215 -0
- data/lib/formtastic/inputs/base/wrapping.rb +50 -0
- data/lib/formtastic/inputs/boolean_input.rb +118 -0
- data/lib/formtastic/inputs/check_boxes_input.rb +197 -0
- data/lib/formtastic/inputs/color_input.rb +42 -0
- data/lib/formtastic/inputs/country_input.rb +86 -0
- data/lib/formtastic/inputs/datalist_input.rb +41 -0
- data/lib/formtastic/inputs/date_picker_input.rb +93 -0
- data/lib/formtastic/inputs/date_select_input.rb +34 -0
- data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
- data/lib/formtastic/inputs/datetime_select_input.rb +12 -0
- data/lib/formtastic/inputs/email_input.rb +41 -0
- data/lib/formtastic/inputs/file_input.rb +42 -0
- data/lib/formtastic/inputs/hidden_input.rb +62 -0
- data/lib/formtastic/inputs/number_input.rb +88 -0
- data/lib/formtastic/inputs/password_input.rb +41 -0
- data/lib/formtastic/inputs/phone_input.rb +42 -0
- data/lib/formtastic/inputs/radio_input.rb +163 -0
- data/lib/formtastic/inputs/range_input.rb +95 -0
- data/lib/formtastic/inputs/search_input.rb +41 -0
- data/lib/formtastic/inputs/select_input.rb +235 -0
- data/lib/formtastic/inputs/string_input.rb +36 -0
- data/lib/formtastic/inputs/text_input.rb +48 -0
- data/lib/formtastic/inputs/time_picker_input.rb +99 -0
- data/lib/formtastic/inputs/time_select_input.rb +38 -0
- data/lib/formtastic/inputs/time_zone_input.rb +58 -0
- data/lib/formtastic/inputs/url_input.rb +41 -0
- data/lib/formtastic/localized_string.rb +17 -0
- data/lib/formtastic/localizer.rb +152 -0
- data/lib/formtastic/namespaced_class_finder.rb +99 -0
- data/lib/formtastic/util.rb +35 -16
- data/lib/formtastic/version.rb +3 -0
- data/lib/generators/formtastic/form/form_generator.rb +64 -37
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/formtastic/install/install_generator.rb +13 -5
- data/lib/generators/templates/_form.html.erb +10 -4
- data/lib/generators/templates/_form.html.haml +8 -4
- data/lib/generators/templates/_form.html.slim +8 -0
- data/lib/generators/templates/formtastic.rb +77 -44
- data/lib/generators/templates/input.rb +19 -0
- data/lib/locale/en.yml +3 -0
- data/sample/basic_inputs.html +224 -0
- data/sample/config.ru +69 -0
- data/sample/index.html +14 -0
- data/spec/action_class_finder_spec.rb +12 -0
- data/spec/actions/button_action_spec.rb +63 -0
- data/spec/actions/generic_action_spec.rb +521 -0
- data/spec/actions/input_action_spec.rb +59 -0
- data/spec/actions/link_action_spec.rb +92 -0
- data/spec/builder/custom_builder_spec.rb +116 -0
- data/spec/builder/error_proc_spec.rb +27 -0
- data/spec/builder/semantic_fields_for_spec.rb +142 -0
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +131 -0
- data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
- data/spec/helpers/action_helper_spec.rb +19 -0
- data/spec/helpers/actions_helper_spec.rb +143 -0
- data/spec/helpers/form_helper_spec.rb +218 -0
- data/spec/helpers/input_helper_spec.rb +6 -0
- data/spec/helpers/inputs_helper_spec.rb +655 -0
- data/spec/helpers/namespaced_action_helper_spec.rb +43 -0
- data/spec/helpers/namespaced_input_helper_spec.rb +36 -0
- data/spec/helpers/reflection_helper_spec.rb +32 -0
- data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
- data/spec/i18n_spec.rb +210 -0
- data/spec/input_class_finder_spec.rb +10 -0
- data/spec/inputs/base/collections_spec.rb +76 -0
- data/spec/inputs/base/validations_spec.rb +342 -0
- data/spec/inputs/boolean_input_spec.rb +254 -0
- data/spec/inputs/check_boxes_input_spec.rb +546 -0
- data/spec/inputs/color_input_spec.rb +97 -0
- data/spec/inputs/country_input_spec.rb +133 -0
- data/spec/inputs/custom_input_spec.rb +55 -0
- data/spec/inputs/datalist_input_spec.rb +61 -0
- data/spec/inputs/date_picker_input_spec.rb +449 -0
- data/spec/inputs/date_select_input_spec.rb +235 -0
- data/spec/inputs/datetime_picker_input_spec.rb +490 -0
- data/spec/inputs/datetime_select_input_spec.rb +193 -0
- data/spec/inputs/email_input_spec.rb +85 -0
- data/spec/inputs/file_input_spec.rb +89 -0
- data/spec/inputs/hidden_input_spec.rb +135 -0
- data/spec/inputs/include_blank_spec.rb +78 -0
- data/spec/inputs/label_spec.rb +149 -0
- data/spec/inputs/number_input_spec.rb +815 -0
- data/spec/inputs/password_input_spec.rb +99 -0
- data/spec/inputs/phone_input_spec.rb +85 -0
- data/spec/inputs/placeholder_spec.rb +71 -0
- data/spec/inputs/radio_input_spec.rb +328 -0
- data/spec/inputs/range_input_spec.rb +505 -0
- data/spec/inputs/readonly_spec.rb +50 -0
- data/spec/inputs/search_input_spec.rb +84 -0
- data/spec/inputs/select_input_spec.rb +615 -0
- data/spec/inputs/string_input_spec.rb +260 -0
- data/spec/inputs/text_input_spec.rb +187 -0
- data/spec/inputs/time_picker_input_spec.rb +455 -0
- data/spec/inputs/time_select_input_spec.rb +248 -0
- data/spec/inputs/time_zone_input_spec.rb +143 -0
- data/spec/inputs/url_input_spec.rb +85 -0
- data/spec/inputs/with_options_spec.rb +43 -0
- data/spec/localizer_spec.rb +130 -0
- data/spec/namespaced_class_finder_spec.rb +79 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +525 -0
- data/spec/support/custom_macros.rb +564 -0
- data/spec/support/deprecation.rb +6 -0
- data/spec/support/shared_examples.rb +1313 -0
- data/spec/support/specialized_class_finder_shared_example.rb +27 -0
- data/spec/support/test_environment.rb +31 -0
- data/spec/util_spec.rb +66 -0
- metadata +434 -161
- data/README.textile +0 -682
- data/generators/form/USAGE +0 -16
- data/generators/form/form_generator.rb +0 -111
- data/generators/formtastic/formtastic_generator.rb +0 -26
- data/init.rb +0 -5
- data/lib/formtastic/layout_helper.rb +0 -12
- data/lib/formtastic/railtie.rb +0 -14
- data/lib/generators/templates/formtastic.css +0 -145
- data/lib/generators/templates/formtastic_changes.css +0 -14
- data/lib/generators/templates/rails2/_form.html.erb +0 -5
- data/lib/generators/templates/rails2/_form.html.haml +0 -4
- 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
|