formtastic 1.2.4 → 3.1.5
Sign up to get free protection for your applications and to get access to all the features.
- 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,99 @@
|
|
1
|
+
module Formtastic
|
2
|
+
# This class implements class resolution in a namespace chain. It
|
3
|
+
# is used both by Formtastic::Helpers::InputHelper and
|
4
|
+
# Formtastic::Helpers::ActionHelper to look up action and input classes.
|
5
|
+
#
|
6
|
+
# @example Implementing own class finder
|
7
|
+
# # You can implement own class finder that for example prefixes the class name or uses custom module.
|
8
|
+
# class MyInputClassFinder < Formtastic::NamespacedClassFinder
|
9
|
+
# def initialize(namespaces)
|
10
|
+
# super [MyNamespace] + namespaces # first lookup in MyNamespace then the defaults
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# private
|
14
|
+
#
|
15
|
+
# def class_name(as)
|
16
|
+
# "My#{super}Input" # for example MyStringInput
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # in config/initializers/formtastic.rb
|
21
|
+
# Formtastic::FormBuilder.input_class_finder = MyInputClassFinder
|
22
|
+
#
|
23
|
+
|
24
|
+
class NamespacedClassFinder
|
25
|
+
attr_reader :namespaces # @private
|
26
|
+
|
27
|
+
# @private
|
28
|
+
class NotFoundError < NameError
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.use_const_defined?
|
32
|
+
defined?(Rails) && ::Rails.application && ::Rails.application.config.respond_to?(:eager_load) && ::Rails.application.config.eager_load
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param namespaces [Array<Module>]
|
36
|
+
def initialize(namespaces)
|
37
|
+
@namespaces = namespaces.flatten
|
38
|
+
@cache = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
# Looks up the given reference in the configured namespaces.
|
42
|
+
#
|
43
|
+
# Two finder methods are provided, one for development tries to
|
44
|
+
# reference the constant directly, triggering Rails' autoloading
|
45
|
+
# const_missing machinery; the second one instead for production
|
46
|
+
# checks with .const_defined before referencing the constant.
|
47
|
+
#
|
48
|
+
def find(as)
|
49
|
+
@cache[as] ||= resolve(as)
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve(as)
|
53
|
+
class_name = class_name(as)
|
54
|
+
|
55
|
+
finder(class_name) or raise NotFoundError, "class #{class_name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Converts symbol to class name
|
59
|
+
# Overridden in subclasses to create `StringInput` and `ButtonAction`
|
60
|
+
# @example
|
61
|
+
# class_name(:string) == "String"
|
62
|
+
|
63
|
+
def class_name(as)
|
64
|
+
as.to_s.camelize
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
if use_const_defined?
|
70
|
+
def finder(class_name) # @private
|
71
|
+
find_with_const_defined(class_name)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
def finder(class_name) # @private
|
75
|
+
find_by_trying(class_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Looks up the given class name in the configured namespaces in order,
|
80
|
+
# returning the first one that has the class name constant defined.
|
81
|
+
def find_with_const_defined(class_name)
|
82
|
+
@namespaces.find do |namespace|
|
83
|
+
if namespace.const_defined?(class_name)
|
84
|
+
break namespace.const_get(class_name)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Use auto-loading in development environment
|
90
|
+
def find_by_trying(class_name)
|
91
|
+
@namespaces.find do |namespace|
|
92
|
+
begin
|
93
|
+
break namespace.const_get(class_name)
|
94
|
+
rescue NameError
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/formtastic/util.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
# Adapted from the rails3 compatibility shim in Haml 2.2
|
4
4
|
module Formtastic
|
5
|
+
# @private
|
5
6
|
module Util
|
6
7
|
extend self
|
7
8
|
## Rails XSS Safety
|
@@ -13,26 +14,44 @@ module Formtastic
|
|
13
14
|
# @param text [String]
|
14
15
|
# @return [String] `text`, marked as HTML-safe
|
15
16
|
def html_safe(text)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
if text.respond_to?(:html_safe)
|
18
|
+
text.html_safe
|
19
|
+
else
|
20
|
+
text
|
21
|
+
end
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
-
# because in Rails 2.3.6 ActionView::SafeBuffer exists
|
25
|
-
# but is a deprecated proxy object.
|
26
|
-
return ActiveSupport::SafeBuffer if defined?(ActiveSupport::SafeBuffer)
|
27
|
-
return ActionView::SafeBuffer
|
24
|
+
def rails3?
|
25
|
+
match?(rails_version, "~> 3.0")
|
28
26
|
end
|
29
27
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
28
|
+
def rails4?
|
29
|
+
match?(rails_version, "~> 4.0")
|
30
|
+
end
|
31
|
+
|
32
|
+
def rails4_0?
|
33
|
+
match?(rails_version, "~> 4.0.0")
|
34
|
+
end
|
35
|
+
|
36
|
+
def rails4_1?
|
37
|
+
match?(rails_version, "~> 4.1.0")
|
38
|
+
end
|
39
|
+
|
40
|
+
def deprecated_version_of_rails?
|
41
|
+
match?(rails_version, "< #{minimum_version_of_rails}")
|
36
42
|
end
|
43
|
+
|
44
|
+
def minimum_version_of_rails
|
45
|
+
"4.1.0"
|
46
|
+
end
|
47
|
+
|
48
|
+
def rails_version
|
49
|
+
::Rails::VERSION::STRING
|
50
|
+
end
|
51
|
+
|
52
|
+
def match?(version, dependency)
|
53
|
+
Gem::Dependency.new("formtastic", dependency).match?("formtastic", version)
|
54
|
+
end
|
55
|
+
|
37
56
|
end
|
38
57
|
end
|
@@ -1,54 +1,59 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Formtastic
|
3
|
+
# Generates a Formtastic form partial based on an existing model. It will not overwrite existing
|
4
|
+
# files without confirmation.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# !!!shell
|
8
|
+
# $ rails generate formtastic:form Post
|
9
|
+
# @example Copy the partial code to the pasteboard rather than generating a partial
|
10
|
+
# !!!shell
|
11
|
+
# $ rails generate formtastic:form Post --copy
|
12
|
+
# @example Return HAML or Slim output instead of default ERB
|
13
|
+
# !!!shell
|
14
|
+
# $ rails generate formtastic:form Post --template-engine haml
|
15
|
+
# $ rails generate formtastic:form Post --template-engine slim
|
16
|
+
# @example Generate a form for specific model attributes
|
17
|
+
# !!!shell
|
18
|
+
# $ rails generate formtastic:form Post title:string body:text
|
19
|
+
# @example Generate a form for a specific controller
|
20
|
+
# !!!shell
|
21
|
+
# $ rails generate formtastic:form Post --controller admin/posts
|
3
22
|
class FormGenerator < Rails::Generators::NamedBase
|
4
|
-
desc "Generates
|
5
|
-
"generated code will be printed out directly in the terminal, and also copied " <<
|
6
|
-
"to clipboard. Can optionally be saved into partial directly."
|
23
|
+
desc "Generates a Formtastic form partial based on an existing model."
|
7
24
|
|
8
|
-
argument :name, :type => :string, :required => true, :banner => '
|
9
|
-
argument :attributes, :type => :array, :default => [], :banner => '
|
25
|
+
argument :name, :type => :string, :required => true, :banner => 'MODEL_NAME'
|
26
|
+
argument :attributes, :type => :array, :default => [], :banner => 'attribute attribute'
|
10
27
|
|
11
|
-
|
12
|
-
:desc => "Generate HAML instead of ERB"
|
28
|
+
source_root File.expand_path('../../../templates', __FILE__)
|
13
29
|
|
14
|
-
class_option :
|
15
|
-
:desc => 'Generate a form partial in the model views path, i.e. "_form.html.erb" or "_form.html.haml"'
|
30
|
+
class_option :template_engine
|
16
31
|
|
17
|
-
class_option :
|
18
|
-
|
32
|
+
class_option :copy, :type => :boolean, :default => false, :group => :formtastic,
|
33
|
+
:desc => 'Copy the generated code the clipboard instead of generating a partial file."'
|
19
34
|
|
20
|
-
|
35
|
+
class_option :controller, :type => :string, :default => false, :group => :formtastic,
|
36
|
+
:desc => 'Generate for custom controller/view path - in case model and controller namespace is different, i.e. "admin/posts"'
|
21
37
|
|
22
38
|
def create_or_show
|
23
|
-
@attributes =
|
39
|
+
@attributes = reflected_attributes if @attributes.empty?
|
24
40
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
template = File.read("#{self.class.source_root}/_form.html.#{template_type}")
|
41
|
+
engine = options[:template_engine]
|
42
|
+
|
43
|
+
if options[:copy]
|
44
|
+
template = File.read("#{self.class.source_root}/_form.html.#{engine}")
|
30
45
|
erb = ERB.new(template, nil, '-')
|
31
46
|
generated_code = erb.result(binding).strip rescue nil
|
32
|
-
|
33
|
-
puts "
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
puts generated_code || "Nothing could be generated - model exists?"
|
38
|
-
puts
|
39
|
-
puts "# ---------------------------------------------------------"
|
40
|
-
puts "Copied to clipboard - just paste it!" if save_to_clipboard(generated_code)
|
47
|
+
puts "The following code has been copied to the clipboard, just paste it in your views:" if save_to_clipboard(generated_code)
|
48
|
+
puts generated_code || "Error: Nothing generated. Does the model exist?"
|
49
|
+
else
|
50
|
+
empty_directory "app/views/#{controller_path}"
|
51
|
+
template "_form.html.#{engine}", "app/views/#{controller_path}/_form.html.#{engine}"
|
41
52
|
end
|
42
53
|
end
|
43
54
|
|
44
55
|
protected
|
45
56
|
|
46
|
-
IGNORED_COLUMNS = [:updated_at, :created_at].freeze
|
47
|
-
|
48
|
-
def template_type
|
49
|
-
@template_type ||= options[:haml] ? :haml : :erb
|
50
|
-
end
|
51
|
-
|
52
57
|
def controller_path
|
53
58
|
@controller_path ||= if options[:controller]
|
54
59
|
options[:controller].underscore
|
@@ -57,8 +62,29 @@ module Formtastic
|
|
57
62
|
end
|
58
63
|
end
|
59
64
|
|
60
|
-
def
|
61
|
-
|
65
|
+
def reflected_attributes
|
66
|
+
columns = content_columns
|
67
|
+
columns += association_columns
|
68
|
+
end
|
69
|
+
|
70
|
+
def model
|
71
|
+
@model ||= name.camelize.constantize
|
72
|
+
end
|
73
|
+
|
74
|
+
# Collects content columns (non-relation columns) for the current class.
|
75
|
+
# Skips Active Record Timestamps.
|
76
|
+
def content_columns
|
77
|
+
model.content_columns.select do |column|
|
78
|
+
!Formtastic::FormBuilder.skipped_columns.include? column.name.to_sym
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Collects association columns (relation columns) for the current class. Skips polymorphic
|
83
|
+
# associations because we can't guess which class to use for an automatically generated input.
|
84
|
+
def association_columns
|
85
|
+
model.reflect_on_all_associations(:belongs_to).select do |association_reflection|
|
86
|
+
association_reflection.options[:polymorphic] != true
|
87
|
+
end
|
62
88
|
end
|
63
89
|
|
64
90
|
def save_to_clipboard(data)
|
@@ -75,10 +101,11 @@ module Formtastic
|
|
75
101
|
`echo "#{data}" | xsel --clipboard` || `echo "#{data}" | xclip`
|
76
102
|
end
|
77
103
|
rescue LoadError
|
78
|
-
|
104
|
+
false
|
79
105
|
else
|
80
|
-
|
106
|
+
true
|
81
107
|
end
|
82
108
|
end
|
109
|
+
|
83
110
|
end
|
84
111
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Formtastic
|
2
|
+
|
3
|
+
# Modify existing inputs, subclass them, or create your own from scratch.
|
4
|
+
# @example
|
5
|
+
# !!!shell
|
6
|
+
# $ rails generate formtastic:input HatSize
|
7
|
+
|
8
|
+
# @example Define input name using underscore convention
|
9
|
+
# !!!shell
|
10
|
+
# $ rails generate formtastic:input hat_size
|
11
|
+
|
12
|
+
# @example Override an existing input behavior
|
13
|
+
# !!!shell
|
14
|
+
# $ rails generate formtastic:input string --extend
|
15
|
+
|
16
|
+
# @example Extend an existing input behavior
|
17
|
+
# !!!shell
|
18
|
+
# $ rails generate formtastic:input FlexibleText --extend string
|
19
|
+
class InputGenerator < Rails::Generators::NamedBase
|
20
|
+
|
21
|
+
argument :name, :type => :string, :required => true, :banner => 'FILE_NAME'
|
22
|
+
|
23
|
+
source_root File.expand_path('../../../templates', __FILE__)
|
24
|
+
|
25
|
+
class_option :extend
|
26
|
+
|
27
|
+
def create
|
28
|
+
normalize_file_name
|
29
|
+
define_extension_sentence
|
30
|
+
template "input.rb", "app/inputs/#{name.underscore}_input.rb"
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def normalize_file_name
|
36
|
+
name.chomp!("Input") if name.ends_with?("Input")
|
37
|
+
name.chomp!("_input") if name.ends_with?("_input")
|
38
|
+
name.chomp!("input") if name.ends_with?("input")
|
39
|
+
end
|
40
|
+
|
41
|
+
def define_extension_sentence
|
42
|
+
@extension_sentence = "< Formtastic::Inputs::#{name.camelize}Input" if options[:extend] == "extend"
|
43
|
+
@extension_sentence ||= "< Formtastic::Inputs::#{options[:extend].camelize}Input" if options[:extend]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,15 +1,23 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
module Formtastic
|
4
|
+
# Copies a config initializer to config/initializers/formtastic.rb
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# !!!shell
|
8
|
+
# $ rails generate formtastic:install
|
3
9
|
class InstallGenerator < Rails::Generators::Base
|
4
|
-
desc "Copies formtastic.css and formtastic_changes.css to public/stylesheets/ and a config initializer to config/initializers/formtastic_config.rb"
|
5
|
-
|
6
10
|
source_root File.expand_path('../../../templates', __FILE__)
|
11
|
+
class_option :template_engine
|
7
12
|
|
13
|
+
desc "Copies a config initializer to config/initializers/formtastic.rb"
|
8
14
|
def copy_files
|
9
|
-
|
15
|
+
copy_file 'formtastic.rb', 'config/initializers/formtastic.rb'
|
16
|
+
end
|
10
17
|
|
11
|
-
|
12
|
-
|
18
|
+
def copy_scaffold_template
|
19
|
+
engine = options[:template_engine]
|
20
|
+
copy_file "_form.html.#{engine}", "lib/templates/#{engine}/scaffold/_form.html.#{engine}"
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<%%=
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
<%%= semantic_form_for @<%= singular_name %> do |f| %>
|
2
|
+
<%%= f.inputs do %>
|
3
|
+
<%- attributes.each do |attribute| -%>
|
4
|
+
<%%= f.input :<%= attribute.name %> %>
|
5
|
+
<%- end -%>
|
6
|
+
<%% end %>
|
7
|
+
|
8
|
+
<%%= f.actions do %>
|
9
|
+
<%%= f.action :submit, :as => :input %>
|
10
|
+
<%% end %>
|
5
11
|
<%% end %>
|
@@ -1,4 +1,8 @@
|
|
1
|
-
=
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
= semantic_form_for @<%= singular_name %> do |f|
|
2
|
+
= f.inputs do
|
3
|
+
<%- attributes.each do |attribute| -%>
|
4
|
+
= f.input :<%= attribute.name %>
|
5
|
+
<%- end -%>
|
6
|
+
|
7
|
+
= f.actions do
|
8
|
+
= f.action :submit, :as => :input
|
@@ -1,80 +1,113 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# --------------------------------------------------------------------------------------------------
|
4
|
-
# Please note: If you're subclassing Formtastic::SemanticFormBuilder in a Rails 3 project,
|
5
|
-
# Formtastic uses class_attribute for these configuration attributes instead of the deprecated
|
6
|
-
# class_inheritable_attribute. The behaviour is slightly different with subclasses (especially
|
7
|
-
# around attributes with Hash or Array) values, so make sure you understand what's happening.
|
8
|
-
# See the documentation for class_attribute in ActiveSupport for more information.
|
9
|
-
# --------------------------------------------------------------------------------------------------
|
10
|
-
|
11
3
|
# Set the default text field size when input is a string. Default is nil.
|
12
|
-
# Formtastic::
|
4
|
+
# Formtastic::FormBuilder.default_text_field_size = 50
|
13
5
|
|
14
6
|
# Set the default text area height when input is a text. Default is 20.
|
15
|
-
# Formtastic::
|
7
|
+
# Formtastic::FormBuilder.default_text_area_height = 5
|
16
8
|
|
17
9
|
# Set the default text area width when input is a text. Default is nil.
|
18
|
-
# Formtastic::
|
10
|
+
# Formtastic::FormBuilder.default_text_area_width = 50
|
19
11
|
|
20
12
|
# Should all fields be considered "required" by default?
|
21
|
-
# Rails 2 only, ignored by Rails 3 because it will never fall back to this default.
|
22
13
|
# Defaults to true.
|
23
|
-
# Formtastic::
|
14
|
+
# Formtastic::FormBuilder.all_fields_required_by_default = true
|
24
15
|
|
25
16
|
# Should select fields have a blank option/prompt by default?
|
26
17
|
# Defaults to true.
|
27
|
-
# Formtastic::
|
18
|
+
# Formtastic::FormBuilder.include_blank_for_select_by_default = true
|
28
19
|
|
29
|
-
# Set the string that will be appended to the labels/fieldsets which are required
|
20
|
+
# Set the string that will be appended to the labels/fieldsets which are required.
|
30
21
|
# It accepts string or procs and the default is a localized version of
|
31
22
|
# '<abbr title="required">*</abbr>'. In other words, if you configure formtastic.required
|
32
23
|
# in your locale, it will replace the abbr title properly. But if you don't want to use
|
33
|
-
# abbr tag, you can simply give a string as below
|
34
|
-
# Formtastic::
|
24
|
+
# abbr tag, you can simply give a string as below.
|
25
|
+
# Formtastic::FormBuilder.required_string = "(required)"
|
35
26
|
|
36
|
-
# Set the string that will be appended to the labels/fieldsets which are optional
|
37
|
-
# Defaults to an empty string ("") and also accepts procs (see required_string above)
|
38
|
-
# Formtastic::
|
27
|
+
# Set the string that will be appended to the labels/fieldsets which are optional.
|
28
|
+
# Defaults to an empty string ("") and also accepts procs (see required_string above).
|
29
|
+
# Formtastic::FormBuilder.optional_string = "(optional)"
|
39
30
|
|
40
31
|
# Set the way inline errors will be displayed.
|
41
32
|
# Defaults to :sentence, valid options are :sentence, :list, :first and :none
|
42
|
-
# Formtastic::
|
33
|
+
# Formtastic::FormBuilder.inline_errors = :sentence
|
43
34
|
# Formtastic uses the following classes as default for hints, inline_errors and error list
|
44
35
|
|
45
|
-
# If you override the class here, please ensure to override it in your
|
46
|
-
# Formtastic::
|
47
|
-
# Formtastic::
|
48
|
-
# Formtastic::
|
36
|
+
# If you override the class here, please ensure to override it in your stylesheets as well.
|
37
|
+
# Formtastic::FormBuilder.default_hint_class = "inline-hints"
|
38
|
+
# Formtastic::FormBuilder.default_inline_error_class = "inline-errors"
|
39
|
+
# Formtastic::FormBuilder.default_error_list_class = "errors"
|
49
40
|
|
50
41
|
# Set the method to call on label text to transform or format it for human-friendly
|
51
42
|
# reading when formtastic is used without object. Defaults to :humanize.
|
52
|
-
# Formtastic::
|
43
|
+
# Formtastic::FormBuilder.label_str_method = :humanize
|
53
44
|
|
54
45
|
# Set the array of methods to try calling on parent objects in :select and :radio inputs
|
55
46
|
# for the text inside each @<option>@ tag or alongside each radio @<input>@. The first method
|
56
47
|
# that is found on the object will be used.
|
57
48
|
# Defaults to ["to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
|
58
|
-
# Formtastic::
|
49
|
+
# Formtastic::FormBuilder.collection_label_methods = [
|
59
50
|
# "to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
|
60
51
|
|
61
|
-
# Formtastic by default renders inside li tags the input, hints and then
|
62
|
-
# errors messages. Sometimes you want the hints to be rendered first than
|
63
|
-
# the input, in the following order: hints, input and errors. You can
|
64
|
-
# customize it doing just as below:
|
65
|
-
# Formtastic::SemanticFormBuilder.inline_order = [:input, :hints, :errors]
|
66
|
-
|
67
|
-
# Additionally, you can customize the order for specific types of inputs.
|
68
|
-
# This is configured on a type basis and if a type is not found it will
|
69
|
-
# fall back to the default order as defined by #inline_order
|
70
|
-
# Formtastic::SemanticFormBuilder.custom_inline_order[:checkbox] = [:errors, :hints, :input]
|
71
|
-
# Formtastic::SemanticFormBuilder.custom_inline_order[:select] = [:hints, :input, :errors]
|
72
|
-
|
73
52
|
# Specifies if labels/hints for input fields automatically be looked up using I18n.
|
74
|
-
# Default value:
|
53
|
+
# Default value: true. Overridden for specific fields by setting value to true,
|
75
54
|
# i.e. :label => true, or :hint => true (or opposite depending on initialized value)
|
76
|
-
# Formtastic::
|
55
|
+
# Formtastic::FormBuilder.i18n_lookups_by_default = false
|
77
56
|
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# Formtastic::
|
57
|
+
# Specifies if I18n lookups of the default I18n Localizer should be cached to improve performance.
|
58
|
+
# Defaults to true.
|
59
|
+
# Formtastic::FormBuilder.i18n_cache_lookups = false
|
60
|
+
|
61
|
+
# Specifies the class to use for localization lookups. You can create your own
|
62
|
+
# class and use it instead by subclassing Formtastic::Localizer (which is the default).
|
63
|
+
# Formtastic::FormBuilder.i18n_localizer = MyOwnLocalizer
|
64
|
+
|
65
|
+
# You can add custom inputs or override parts of Formtastic by subclassing Formtastic::FormBuilder and
|
66
|
+
# specifying that class here. Defaults to Formtastic::FormBuilder.
|
67
|
+
# Formtastic::Helpers::FormHelper.builder = MyCustomBuilder
|
68
|
+
|
69
|
+
# All formtastic forms have a class that indicates that they are just that. You
|
70
|
+
# can change it to any class you want.
|
71
|
+
# Formtastic::Helpers::FormHelper.default_form_class = 'formtastic'
|
72
|
+
|
73
|
+
# Formtastic will infer a class name from the model, array, string or symbol you pass to the
|
74
|
+
# form builder. You can customize the way that class is presented by overriding
|
75
|
+
# this proc.
|
76
|
+
# Formtastic::Helpers::FormHelper.default_form_model_class_proc = proc { |model_class_name| model_class_name }
|
77
|
+
|
78
|
+
# Allows to set a custom field_error_proc wrapper. By default this wrapper
|
79
|
+
# is disabled since `formtastic` already adds an error class to the LI tag
|
80
|
+
# containing the input.
|
81
|
+
# Formtastic::Helpers::FormHelper.formtastic_field_error_proc = proc { |html_tag, instance_tag| html_tag }
|
82
|
+
|
83
|
+
# You can opt-in to Formtastic's use of the HTML5 `required` attribute on `<input>`, `<select>`
|
84
|
+
# and `<textarea>` tags by setting this to true (defaults to false).
|
85
|
+
# Formtastic::FormBuilder.use_required_attribute = false
|
86
|
+
|
87
|
+
# You can opt-in to new HTML5 browser validations (for things like email and url inputs) by setting
|
88
|
+
# this to true. Doing so will omit the `novalidate` attribute from the `<form>` tag.
|
89
|
+
# See http://diveintohtml5.org/forms.html#validation for more info.
|
90
|
+
# Formtastic::FormBuilder.perform_browser_validations = true
|
91
|
+
|
92
|
+
# By creating custom input class finder, you can change how input classes are looked up.
|
93
|
+
# For example you can make it to search for TextInputFilter instead of TextInput.
|
94
|
+
# See # TODO: add link # for more information
|
95
|
+
# NOTE: this behavior will be default from Formtastic 4.0
|
96
|
+
Formtastic::FormBuilder.input_class_finder = Formtastic::InputClassFinder
|
97
|
+
|
98
|
+
# Define custom namespaces in which to look up your Input classes. Default is
|
99
|
+
# to look up in the global scope and in Formtastic::Inputs.
|
100
|
+
# Formtastic::FormBuilder.input_namespaces = [ ::Object, ::MyInputsModule, ::Formtastic::Inputs ]
|
101
|
+
|
102
|
+
# By creating custom action class finder, you can change how action classes are looked up.
|
103
|
+
# For example you can make it to search for MyButtonAction instead of ButtonAction.
|
104
|
+
# See # TODO: add link # for more information
|
105
|
+
# NOTE: this behavior will be default from Formtastic 4.0
|
106
|
+
Formtastic::FormBuilder.action_class_finder = Formtastic::ActionClassFinder
|
107
|
+
|
108
|
+
# Define custom namespaces in which to look up your Action classes. Default is
|
109
|
+
# to look up in the global scope and in Formtastic::Actions.
|
110
|
+
# Formtastic::FormBuilder.action_namespaces = [ ::Object, ::MyActionsModule, ::Formtastic::Actions ]
|
111
|
+
|
112
|
+
# Which columns to skip when automatically rendering a form without any fields specified.
|
113
|
+
# Formtastic::FormBuilder.skipped_columns = [:created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
|