formtastic 3.1.6 → 4.0.0.rc1
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 +4 -4
- data/.gitattributes +1 -0
- data/.gitignore +3 -2
- data/.travis.yml +28 -40
- data/CHANGELOG.md +49 -0
- data/DEPRECATIONS +1 -1
- data/Gemfile.lock +104 -0
- data/README.md +628 -629
- data/Rakefile +20 -1
- data/app/assets/stylesheets/formtastic.css +1 -1
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +9 -14
- data/gemfiles/rails_5.2/Gemfile +5 -0
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +1 -38
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +8 -24
- data/lib/formtastic/helpers/action_helper.rb +1 -48
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +7 -3
- data/lib/formtastic/helpers/input_helper.rb +18 -76
- data/lib/formtastic/helpers/inputs_helper.rb +12 -3
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/inputs/base/collections.rb +1 -5
- data/lib/formtastic/inputs/base/errors.rb +4 -4
- data/lib/formtastic/inputs/base/hints.rb +1 -1
- data/lib/formtastic/inputs/base/timeish.rb +5 -1
- data/lib/formtastic/inputs/base/validations.rb +19 -9
- data/lib/formtastic/inputs/check_boxes_input.rb +3 -3
- data/lib/formtastic/inputs/color_input.rb +0 -1
- data/lib/formtastic/inputs/select_input.rb +1 -1
- data/lib/formtastic/inputs.rb +32 -29
- data/lib/formtastic/localizer.rb +4 -3
- data/lib/formtastic/version.rb +1 -1
- data/lib/formtastic.rb +5 -11
- data/lib/generators/templates/formtastic.rb +4 -6
- data/script/integration-template.rb +71 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +1 -1
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +60 -60
- data/spec/actions/input_action_spec.rb +7 -7
- data/spec/actions/link_action_spec.rb +10 -10
- data/spec/builder/custom_builder_spec.rb +36 -20
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +27 -27
- data/spec/generators/formtastic/form/form_generator_spec.rb +25 -25
- data/spec/generators/formtastic/input/input_generator_spec.rb +31 -31
- data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
- data/spec/helpers/action_helper_spec.rb +328 -10
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +33 -33
- data/spec/helpers/input_helper_spec.rb +975 -2
- data/spec/helpers/inputs_helper_spec.rb +120 -105
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +22 -22
- data/spec/i18n_spec.rb +26 -26
- data/spec/input_class_finder_spec.rb +1 -1
- data/spec/inputs/base/collections_spec.rb +6 -6
- data/spec/inputs/base/validations_spec.rb +157 -19
- data/spec/inputs/boolean_input_spec.rb +55 -55
- data/spec/inputs/check_boxes_input_spec.rb +96 -95
- data/spec/inputs/color_input_spec.rb +51 -63
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +2 -6
- data/spec/inputs/datalist_input_spec.rb +1 -1
- data/spec/inputs/date_picker_input_spec.rb +42 -42
- data/spec/inputs/date_select_input_spec.rb +51 -37
- data/spec/inputs/datetime_picker_input_spec.rb +46 -46
- data/spec/inputs/datetime_select_input_spec.rb +53 -37
- data/spec/inputs/email_input_spec.rb +5 -5
- data/spec/inputs/file_input_spec.rb +6 -6
- data/spec/inputs/hidden_input_spec.rb +18 -18
- data/spec/inputs/include_blank_spec.rb +8 -8
- data/spec/inputs/label_spec.rb +20 -20
- data/spec/inputs/number_input_spec.rb +112 -112
- data/spec/inputs/password_input_spec.rb +5 -5
- data/spec/inputs/phone_input_spec.rb +5 -5
- data/spec/inputs/placeholder_spec.rb +5 -5
- data/spec/inputs/radio_input_spec.rb +63 -65
- data/spec/inputs/range_input_spec.rb +66 -66
- data/spec/inputs/readonly_spec.rb +4 -4
- data/spec/inputs/search_input_spec.rb +5 -5
- data/spec/inputs/select_input_spec.rb +92 -96
- data/spec/inputs/string_input_spec.rb +23 -23
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +43 -43
- data/spec/inputs/time_select_input_spec.rb +67 -54
- data/spec/inputs/time_zone_input_spec.rb +19 -19
- data/spec/inputs/url_input_spec.rb +5 -5
- data/spec/inputs/with_options_spec.rb +7 -7
- data/spec/localizer_spec.rb +17 -17
- data/spec/namespaced_class_finder_spec.rb +2 -2
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +163 -223
- data/spec/support/custom_macros.rb +72 -75
- data/spec/support/shared_examples.rb +0 -1301
- data/spec/support/test_environment.rb +23 -9
- metadata +36 -122
- data/Appraisals +0 -43
- data/CHANGELOG +0 -54
- data/gemfiles/rails_3.2.gemfile +0 -9
- data/gemfiles/rails_4.0.4.gemfile +0 -8
- data/gemfiles/rails_4.1.gemfile +0 -8
- data/gemfiles/rails_4.2.gemfile +0 -8
- data/gemfiles/rails_4.gemfile +0 -8
- data/gemfiles/rails_5.0.gemfile +0 -8
- data/gemfiles/rails_edge.gemfile +0 -15
- data/lib/formtastic/util.rb +0 -57
- data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
- data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
- data/spec/util_spec.rb +0 -66
data/Rakefile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'bundler/setup'
|
3
|
-
require 'appraisal'
|
4
3
|
require 'yard'
|
5
4
|
require 'rspec/core/rake_task'
|
6
5
|
|
@@ -13,6 +12,26 @@ else
|
|
13
12
|
task :default => :spec
|
14
13
|
end
|
15
14
|
|
15
|
+
desc 'Run the default task over all gemfiles.'
|
16
|
+
task :appraisal do
|
17
|
+
for_all_gemfiles("exec", "rake")
|
18
|
+
end
|
19
|
+
|
20
|
+
namespace :appraisal do
|
21
|
+
desc 'Run `bundle install` over all gemfiles.'
|
22
|
+
task :install do
|
23
|
+
for_all_gemfiles("install")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def for_all_gemfiles(*args)
|
28
|
+
Dir.glob("gemfiles/*/Gemfile").sort.each do |gemfile|
|
29
|
+
Bundler.with_original_env do
|
30
|
+
sh({ "APPRAISAL_INITIALIZED" => "true", "BUNDLE_GEMFILE" => gemfile }, "bundle", *args)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
16
35
|
desc 'Generate documentation for the formtastic plugin.'
|
17
36
|
YARD::Rake::YardocTask.new(:yard) do |t|
|
18
37
|
|
@@ -223,7 +223,7 @@ This stylesheet forms part of the Formtastic Rails Plugin
|
|
223
223
|
/* BOOLEAN LABELS
|
224
224
|
--------------------------------------------------------------------------------------------------*/
|
225
225
|
.formtastic .boolean label {
|
226
|
-
|
226
|
+
margin-left:25%;
|
227
227
|
display:block;
|
228
228
|
}
|
229
229
|
|
data/bin/appraisal
ADDED
data/formtastic.gemspec
CHANGED
@@ -15,27 +15,22 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
-
s.executables =
|
18
|
+
s.executables = []
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.rdoc_options = ["--charset=UTF-8"]
|
22
22
|
s.extra_rdoc_files = ["README.md"]
|
23
23
|
|
24
|
-
s.required_ruby_version = '>=
|
24
|
+
s.required_ruby_version = '>= 2.4.0'
|
25
25
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
26
|
+
s.rubygems_version = %q{1.3.6}
|
26
27
|
|
27
|
-
s.add_dependency(%q<actionpack>, [">=
|
28
|
+
s.add_dependency(%q<actionpack>, [">= 5.2.0"])
|
28
29
|
|
29
|
-
s.add_development_dependency(%q<
|
30
|
-
s.add_development_dependency(%q<rspec-
|
31
|
-
s.add_development_dependency(%q<
|
32
|
-
s.add_development_dependency(%q<hpricot>, ["~> 0.8.3"])
|
33
|
-
s.add_development_dependency(%q<RedCloth>, ["~> 4.2"]) # for YARD Textile formatting
|
34
|
-
s.add_development_dependency(%q<yard>, ["~> 0.8"])
|
35
|
-
s.add_development_dependency(%q<colored>, ["~> 1.2"])
|
36
|
-
s.add_development_dependency(%q<tzinfo>)
|
30
|
+
s.add_development_dependency(%q<rspec-rails>, ["~> 3.4"])
|
31
|
+
s.add_development_dependency(%q<rspec-dom-testing>, [">= 0.1.0"])
|
32
|
+
s.add_development_dependency(%q<yard>, ["~> 0.9.20"])
|
37
33
|
s.add_development_dependency(%q<ammeter>, ["~> 1.1.3"])
|
38
|
-
s.add_development_dependency(%q<
|
39
|
-
s.add_development_dependency(%q<
|
40
|
-
s.add_development_dependency(%q<activemodel>, [">= 3.2.13"])
|
34
|
+
s.add_development_dependency(%q<rake>)
|
35
|
+
s.add_development_dependency(%q<sqlite3>, ["~> 1.4"])
|
41
36
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "rails", git: "https://github.com/rails/rails.git"
|
4
|
+
gem "rack", git: "https://github.com/rack/rack.git"
|
5
|
+
gem "i18n", git: "https://github.com/svenfuchs/i18n.git"
|
6
|
+
gem "arel", git: "https://github.com/rails/arel.git"
|
7
|
+
gem "rspec-rails", git: "https://github.com/rspec/rspec-rails.git"
|
8
|
+
gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
|
9
|
+
gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
|
10
|
+
gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
|
11
|
+
gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
|
12
|
+
|
13
|
+
gemspec path: "../.."
|
data/lib/formtastic/actions.rb
CHANGED
@@ -1,42 +1,5 @@
|
|
1
1
|
require 'active_support/deprecation'
|
2
2
|
|
3
3
|
module Formtastic
|
4
|
-
|
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
|
4
|
+
Deprecation = ActiveSupport::Deprecation
|
42
5
|
end
|
data/lib/formtastic/engine.rb
CHANGED
@@ -21,7 +21,7 @@ module Formtastic
|
|
21
21
|
configure :default_text_area_width
|
22
22
|
configure :all_fields_required_by_default, true
|
23
23
|
configure :include_blank_for_select_by_default, true
|
24
|
-
configure :required_string, proc {
|
24
|
+
configure :required_string, proc { %{<abbr title="#{Formtastic::I18n.t(:required)}">*</abbr>}.html_safe }
|
25
25
|
configure :optional_string, ''
|
26
26
|
configure :inline_errors, :sentence
|
27
27
|
configure :label_str_method, :humanize
|
@@ -42,14 +42,10 @@ module Formtastic
|
|
42
42
|
configure :perform_browser_validations, false
|
43
43
|
# Check {Formtastic::InputClassFinder} to see how are inputs resolved.
|
44
44
|
configure :input_namespaces, [::Object, ::Formtastic::Inputs]
|
45
|
-
|
46
|
-
# Will be {Formtastic::InputClassFinder} by default in 4.0.
|
47
|
-
configure :input_class_finder #, Formtastic::InputClassFinder
|
45
|
+
configure :input_class_finder, Formtastic::InputClassFinder
|
48
46
|
# Check {Formtastic::ActionClassFinder} to see how are inputs resolved.
|
49
47
|
configure :action_namespaces, [::Object, ::Formtastic::Actions]
|
50
|
-
|
51
|
-
# Will be {Formtastic::ActionClassFinder} by default in 4.0.
|
52
|
-
configure :action_class_finder#, Formtastic::ActionClassFinder
|
48
|
+
configure :action_class_finder, Formtastic::ActionClassFinder
|
53
49
|
|
54
50
|
configure :skipped_columns, [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
|
55
51
|
configure :priority_time_zones, []
|
@@ -68,8 +64,8 @@ module Formtastic
|
|
68
64
|
|
69
65
|
# This is a wrapper around Rails' `ActionView::Helpers::FormBuilder#fields_for`, originally
|
70
66
|
# provided to ensure that the `:builder` from `semantic_form_for` was passed down into
|
71
|
-
# the nested `fields_for`. Rails
|
72
|
-
# provided purely for backwards compatibility and DSL consistency.
|
67
|
+
# the nested `fields_for`. Our supported versions of Rails no longer require us to do this,
|
68
|
+
# so this method is provided purely for backwards compatibility and DSL consistency.
|
73
69
|
#
|
74
70
|
# When constructing a `fields_for` form fragment *outside* of `semantic_form_for`, please use
|
75
71
|
# `Formtastic::Helpers::FormHelper#semantic_fields_for`.
|
@@ -95,23 +91,11 @@ module Formtastic
|
|
95
91
|
#
|
96
92
|
# @todo is there a way to test the params structure of the Rails helper we wrap to ensure forward compatibility?
|
97
93
|
def semantic_fields_for(record_or_name_or_array, *args, &block)
|
98
|
-
|
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)
|
94
|
+
fields_for(record_or_name_or_array, *args, &block)
|
104
95
|
end
|
105
96
|
|
106
|
-
def initialize(object_name, object, template, options
|
107
|
-
|
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
|
97
|
+
def initialize(object_name, object, template, options)
|
98
|
+
super
|
115
99
|
|
116
100
|
if respond_to?('multipart=') && options.is_a?(Hash) && options[:html]
|
117
101
|
self.multipart = options[:html][:multipart]
|
@@ -2,9 +2,6 @@
|
|
2
2
|
module Formtastic
|
3
3
|
module Helpers
|
4
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
5
|
# Renders an action for the form (such as a subit/reset button, or a cancel link).
|
9
6
|
#
|
10
7
|
# Each action is wrapped in an `<li class="action">` tag with other classes added based on the
|
@@ -82,7 +79,7 @@ module Formtastic
|
|
82
79
|
options = options.dup # Allow options to be shared without being tainted by Formtastic
|
83
80
|
options[:as] ||= default_action_type(method, options)
|
84
81
|
|
85
|
-
klass =
|
82
|
+
klass = namespaced_action_class(options[:as])
|
86
83
|
|
87
84
|
klass.new(self, template, @object, @object_name, method, options).to_html
|
88
85
|
end
|
@@ -113,50 +110,6 @@ module Formtastic
|
|
113
110
|
rescue Formtastic::ActionClassFinder::NotFoundError => e
|
114
111
|
raise Formtastic::UnknownActionError, "Unable to find action #{e.message}"
|
115
112
|
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
113
|
end
|
161
114
|
end
|
162
115
|
end
|
@@ -52,7 +52,7 @@ module Formtastic
|
|
52
52
|
return nil if full_errors.blank?
|
53
53
|
html_options[:class] ||= "errors"
|
54
54
|
template.content_tag(:ul, html_options) do
|
55
|
-
|
55
|
+
full_errors.map { |error| template.content_tag(:li, error) }.join.html_safe
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -78,4 +78,4 @@ module Formtastic
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
end
|
81
|
+
end
|
@@ -33,12 +33,15 @@ module Formtastic
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
# Work-around for empty contents block
|
37
|
+
contents ||= ""
|
38
|
+
|
36
39
|
# Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
|
37
40
|
contents = contents.join if contents.respond_to?(:join)
|
38
41
|
|
39
42
|
legend = field_set_legend(html_options)
|
40
43
|
fieldset = template.content_tag(:fieldset,
|
41
|
-
|
44
|
+
legend.html_safe << template.content_tag(:ol, contents.html_safe),
|
42
45
|
html_options.except(:builder, :parent, :name)
|
43
46
|
)
|
44
47
|
|
@@ -47,8 +50,9 @@ module Formtastic
|
|
47
50
|
|
48
51
|
def field_set_legend(html_options)
|
49
52
|
legend = (html_options[:name] || '').to_s
|
50
|
-
|
51
|
-
legend
|
53
|
+
# only applying if String includes '%i' avoids argument error when $DEBUG is true
|
54
|
+
legend %= parent_child_index(html_options[:parent]) if html_options[:parent] && legend.include?('%i')
|
55
|
+
legend = template.content_tag(:legend, template.content_tag(:span, legend.html_safe)) unless legend.blank?
|
52
56
|
legend
|
53
57
|
end
|
54
58
|
|
@@ -36,9 +36,6 @@ module Formtastic
|
|
36
36
|
# @see Formtastic::Helpers::InputsHelper#inputs
|
37
37
|
# @see Formtastic::Helpers::FormHelper#semantic_form_for
|
38
38
|
module InputHelper
|
39
|
-
INPUT_CLASS_DEPRECATION = 'configure Formtastic::FormBuilder.input_class_finder instead (upgrade guide on wiki: http://bit.ly/1F9QtKc )'.freeze
|
40
|
-
private_constant(:INPUT_CLASS_DEPRECATION)
|
41
|
-
|
42
39
|
include Formtastic::Helpers::Reflection
|
43
40
|
include Formtastic::Helpers::Enum
|
44
41
|
include Formtastic::Helpers::FileColumnDetection
|
@@ -237,7 +234,7 @@ module Formtastic
|
|
237
234
|
options = options.dup # Allow options to be shared without being tainted by Formtastic
|
238
235
|
options[:as] ||= default_input_type(method, options)
|
239
236
|
|
240
|
-
klass =
|
237
|
+
klass = namespaced_input_class(options[:as])
|
241
238
|
|
242
239
|
klass.new(self, template, @object, @object_name, method, options).to_html
|
243
240
|
end
|
@@ -286,6 +283,10 @@ module Formtastic
|
|
286
283
|
return :time_select
|
287
284
|
when :date
|
288
285
|
return :date_select
|
286
|
+
when :hstore, :json, :jsonb
|
287
|
+
return :text
|
288
|
+
when :citext, :inet
|
289
|
+
return :string
|
289
290
|
end
|
290
291
|
|
291
292
|
# Try look for hints in options hash. Quite common senario: Enum keys stored as string in the database.
|
@@ -300,12 +301,20 @@ module Formtastic
|
|
300
301
|
end
|
301
302
|
|
302
303
|
# Get a column object for a specified attribute method - if possible.
|
304
|
+
# @return [ActiveModel::Type::Value, #type] in case of rails 5 attributes api
|
305
|
+
# @return [ActiveRecord::ConnectionAdapters::Column] in case of rails 4
|
303
306
|
def column_for(method) # @private
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
307
|
+
case
|
308
|
+
when @object.class.respond_to?(:type_for_attribute)
|
309
|
+
@object.class.type_for_attribute(method.to_s)
|
310
|
+
when @object.class.respond_to?(:column_for_attribute)
|
311
|
+
@object.class.column_for_attribute(method)
|
312
|
+
when @object.respond_to?(:column_for_attribute)
|
313
|
+
# Remove deprecation wrapper & review after Rails 5.0 ships
|
314
|
+
ActiveSupport::Deprecation.silence do
|
315
|
+
@object.column_for_attribute(method)
|
316
|
+
end
|
317
|
+
else nil
|
309
318
|
end
|
310
319
|
end
|
311
320
|
|
@@ -335,73 +344,6 @@ module Formtastic
|
|
335
344
|
rescue Formtastic::InputClassFinder::NotFoundError
|
336
345
|
raise Formtastic::UnknownInputError, "Unable to find input #{$!.message}"
|
337
346
|
end
|
338
|
-
|
339
|
-
# @api private
|
340
|
-
# @deprecated Use {#namespaced_input_class} instead.
|
341
|
-
def input_class(as)
|
342
|
-
return namespaced_input_class(as) if input_class_finder
|
343
|
-
|
344
|
-
input_class_deprecation_warning(__method__)
|
345
|
-
|
346
|
-
@input_classes_cache ||= {}
|
347
|
-
@input_classes_cache[as] ||= begin
|
348
|
-
config = Rails.application.config
|
349
|
-
use_const_defined = config.respond_to?(:eager_load) ? config.eager_load : config.cache_classes
|
350
|
-
use_const_defined ? input_class_with_const_defined(as) : input_class_by_trying(as)
|
351
|
-
end
|
352
|
-
end
|
353
|
-
|
354
|
-
# @api private
|
355
|
-
# @deprecated Use {InputClassFinder#find} instead.
|
356
|
-
# prevent exceptions in production environment for better performance
|
357
|
-
def input_class_with_const_defined(as)
|
358
|
-
input_class_name = custom_input_class_name(as)
|
359
|
-
|
360
|
-
if ::Object.const_defined?(input_class_name)
|
361
|
-
input_class_name.constantize
|
362
|
-
elsif Formtastic::Inputs.const_defined?(input_class_name)
|
363
|
-
standard_input_class_name(as).constantize
|
364
|
-
else
|
365
|
-
raise Formtastic::UnknownInputError, "Unable to find input class #{input_class_name}"
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
# @api private
|
370
|
-
# @deprecated Use {InputClassFinder#find} instead.
|
371
|
-
# use auto-loading in development environment
|
372
|
-
def input_class_by_trying(as)
|
373
|
-
begin
|
374
|
-
custom_input_class_name(as).constantize
|
375
|
-
rescue NameError
|
376
|
-
standard_input_class_name(as).constantize
|
377
|
-
end
|
378
|
-
rescue NameError
|
379
|
-
raise Formtastic::UnknownInputError, "Unable to find input class for #{as}"
|
380
|
-
end
|
381
|
-
|
382
|
-
# @api private
|
383
|
-
# @deprecated Use {InputClassFinder#class_name} instead.
|
384
|
-
# :as => :string # => StringInput
|
385
|
-
def custom_input_class_name(as)
|
386
|
-
input_class_deprecation_warning(__method__)
|
387
|
-
"#{as.to_s.camelize}Input"
|
388
|
-
end
|
389
|
-
|
390
|
-
# @api private
|
391
|
-
# @deprecated Use {InputClassFinder#class_name} instead.
|
392
|
-
# :as => :string # => {Formtastic::Inputs::StringInput}
|
393
|
-
def standard_input_class_name(as)
|
394
|
-
input_class_deprecation_warning(__method__)
|
395
|
-
"Formtastic::Inputs::#{as.to_s.camelize}Input"
|
396
|
-
end
|
397
|
-
|
398
|
-
private
|
399
|
-
|
400
|
-
def input_class_deprecation_warning(method)
|
401
|
-
@input_class_deprecation_warned ||=
|
402
|
-
Formtastic.deprecation.deprecation_warning(method, INPUT_CLASS_DEPRECATION, caller(2))
|
403
|
-
end
|
404
|
-
|
405
347
|
end
|
406
348
|
end
|
407
349
|
end
|
@@ -215,7 +215,7 @@ module Formtastic
|
|
215
215
|
# <%= f.input :title ... %>
|
216
216
|
# <%= f.input :body ... %>
|
217
217
|
# <% end %>
|
218
|
-
# <%= f.inputs
|
218
|
+
# <%= f.inputs :name => 'Advanced options:' do %>
|
219
219
|
# <%= f.input :user ... %>
|
220
220
|
# <%= f.input :categories ... %>
|
221
221
|
# <% end %>
|
@@ -310,7 +310,7 @@ module Formtastic
|
|
310
310
|
def default_columns_for_object
|
311
311
|
cols = association_columns(:belongs_to)
|
312
312
|
cols += content_columns
|
313
|
-
cols -=
|
313
|
+
cols -= skipped_columns
|
314
314
|
cols.compact
|
315
315
|
end
|
316
316
|
|
@@ -350,12 +350,21 @@ module Formtastic
|
|
350
350
|
end
|
351
351
|
end
|
352
352
|
|
353
|
+
# Collects all foreign key columns
|
354
|
+
def foreign_key_columns # @private
|
355
|
+
if @object.present? && @object.class.respond_to?(:reflect_on_all_associations)
|
356
|
+
@object.class.reflect_on_all_associations(:belongs_to).map(&:foreign_key)
|
357
|
+
else
|
358
|
+
[]
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
353
362
|
# Collects content columns (non-relation columns) for the current form object class.
|
354
363
|
def content_columns # @private
|
355
364
|
# TODO: NameError is raised by Inflector.constantize. Consider checking if it exists instead.
|
356
365
|
begin klass = model_name.constantize; rescue NameError; return [] end
|
357
366
|
return [] unless klass.respond_to?(:content_columns)
|
358
|
-
klass.content_columns.collect { |c| c.name.to_sym }.compact
|
367
|
+
klass.content_columns.collect { |c| c.name.to_sym }.compact - foreign_key_columns
|
359
368
|
end
|
360
369
|
|
361
370
|
# Deals with :for option when it's supplied to inputs methods. Additional
|
data/lib/formtastic/i18n.rb
CHANGED
@@ -23,7 +23,7 @@ module Formtastic
|
|
23
23
|
options = args.extract_options!
|
24
24
|
options.reverse_merge!(:default => DEFAULT_VALUES[key])
|
25
25
|
options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
|
26
|
-
::I18n.translate(key, *
|
26
|
+
::I18n.translate(key, *args, **options)
|
27
27
|
end
|
28
28
|
alias :t :translate
|
29
29
|
|
@@ -84,11 +84,7 @@ module Formtastic
|
|
84
84
|
scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
|
85
85
|
where_conditions = (scope_conditions && scope_conditions[:conditions]) || {}
|
86
86
|
|
87
|
-
|
88
|
-
reflection.klass.scoped(scope_conditions).where({}) # where is uneccessary, but keeps the stubbing simpler while we support rails3
|
89
|
-
else
|
90
|
-
reflection.klass.where(where_conditions)
|
91
|
-
end
|
87
|
+
reflection.klass.where(where_conditions)
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
@@ -9,21 +9,21 @@ module Formtastic
|
|
9
9
|
|
10
10
|
def error_sentence_html
|
11
11
|
error_class = builder.default_inline_error_class
|
12
|
-
template.content_tag(:p,
|
12
|
+
template.content_tag(:p, errors.to_sentence, :class => error_class)
|
13
13
|
end
|
14
14
|
|
15
15
|
def error_list_html
|
16
16
|
error_class = builder.default_error_list_class
|
17
17
|
list_elements = []
|
18
18
|
errors.each do |error|
|
19
|
-
list_elements << template.content_tag(:li,
|
19
|
+
list_elements << template.content_tag(:li, error.html_safe)
|
20
20
|
end
|
21
|
-
template.content_tag(:ul,
|
21
|
+
template.content_tag(:ul, list_elements.join("\n").html_safe, :class => error_class)
|
22
22
|
end
|
23
23
|
|
24
24
|
def error_first_html
|
25
25
|
error_class = builder.default_inline_error_class
|
26
|
-
template.content_tag(:p,
|
26
|
+
template.content_tag(:p, errors.first.untaint.html_safe, :class => error_class)
|
27
27
|
end
|
28
28
|
|
29
29
|
def error_none_html
|
@@ -85,6 +85,9 @@ module Formtastic
|
|
85
85
|
# <%= f.input :publish_at, :as => :time_select, :include_blank => true %>
|
86
86
|
# <%= f.input :publish_at, :as => :time_select, :include_blank => false %>
|
87
87
|
#
|
88
|
+
# @example Provide a value for the field via selected
|
89
|
+
# <%= f.input :publish_at, :as => :datetime_select, :selected => DateTime.new(2018, 10, 4, 12, 00)
|
90
|
+
#
|
88
91
|
# @todo Document i18n
|
89
92
|
# @todo Check what other Rails options are supported (`start_year`, `end_year`, `use_month_numbers`, `use_short_month`, `add_month_numbers`, `prompt`), write tests for them, and otherwise support them
|
90
93
|
# @todo Could we take the rendering from Rails' helpers and inject better HTML in and around it rather than re-inventing the whee?
|
@@ -157,6 +160,7 @@ module Formtastic
|
|
157
160
|
end
|
158
161
|
|
159
162
|
def value
|
163
|
+
return input_options[:selected] if options.key?(:selected)
|
160
164
|
object.send(method) if object && object.respond_to?(method)
|
161
165
|
end
|
162
166
|
|
@@ -238,4 +242,4 @@ module Formtastic
|
|
238
242
|
end
|
239
243
|
end
|
240
244
|
end
|
241
|
-
end
|
245
|
+
end
|