formtastic 1.2.4 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
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,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
@@ -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
- return text if text.nil?
17
- return text.html_safe if defined?(ActiveSupport::SafeBuffer)
18
- return text.html_safe! if text.respond_to?(:html_safe!)
19
- text
17
+ if text.respond_to?(:html_safe)
18
+ text.html_safe
19
+ else
20
+ text
21
+ end
20
22
  end
21
23
 
22
- def rails_safe_buffer_class
23
- # It's important that we check ActiveSupport first,
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 rails3?
31
- version=
32
- if defined?(ActionPack::VERSION::MAJOR)
33
- ActionPack::VERSION::MAJOR
34
- end
35
- !version.blank? && version >= 3
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
@@ -0,0 +1,3 @@
1
+ module Formtastic
2
+ VERSION = "3.1.5"
3
+ 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 formtastic form code based on an existing model. By default the " <<
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 => 'ExistingModelName'
9
- argument :attributes, :type => :array, :default => [], :banner => 'field:type field:type'
25
+ argument :name, :type => :string, :required => true, :banner => 'MODEL_NAME'
26
+ argument :attributes, :type => :array, :default => [], :banner => 'attribute attribute'
10
27
 
11
- class_option :haml, :type => :boolean, :default => false, :group => :formtastic,
12
- :desc => "Generate HAML instead of ERB"
28
+ source_root File.expand_path('../../../templates', __FILE__)
13
29
 
14
- class_option :partial, :type => :boolean, :default => false, :group => :formtastic,
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 :controller, :type => :string, :default => false, :group => :formtastic,
18
- :desc => 'Generate for custom controller/view path - in case model and controller namespace is different, i.e. "admin/posts"'
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
- source_root File.expand_path('../../../templates', __FILE__)
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 = self.columns if @attributes.empty?
39
+ @attributes = reflected_attributes if @attributes.empty?
24
40
 
25
- if options[:partial]
26
- empty_directory "app/views/#{controller_path}"
27
- template "_form.html.#{template_type}", "app/views/#{controller_path}/_form.html.#{template_type}"
28
- else
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
- puts "# GENERATED FORMTASTIC CODE"
35
- puts "# ---------------------------------------------------------"
36
- puts
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 columns
61
- @columns ||= self.name.camelize.constantize.content_columns.reject { |column| IGNORED_COLUMNS.include?(column.name.to_sym) }
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
- false
104
+ false
79
105
  else
80
- true
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
- template 'formtastic.rb', 'config/initializers/formtastic.rb'
15
+ copy_file 'formtastic.rb', 'config/initializers/formtastic.rb'
16
+ end
10
17
 
11
- template 'formtastic.css', 'public/stylesheets/formtastic.css'
12
- template 'formtastic_changes.css', 'public/stylesheets/formtastic_changes.css'
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
- <%%= f.inputs do %>
2
- <% attributes.each do |attribute| -%>
3
- <%%= f.input :<%= attribute.name %> %>
4
- <% end -%>
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
- = f.inputs do
2
- <% attributes.each do |attribute| -%>
3
- = f.input :<%= attribute.name %>
4
- <% end -%>
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
@@ -0,0 +1,8 @@
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::SemanticFormBuilder.default_text_field_size = 50
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::SemanticFormBuilder.default_text_area_height = 5
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::SemanticFormBuilder.default_text_area_width = 50
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::SemanticFormBuilder.all_fields_required_by_default = true
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::SemanticFormBuilder.include_blank_for_select_by_default = true
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::SemanticFormBuilder.required_string = "(required)"
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::SemanticFormBuilder.optional_string = "(optional)"
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::SemanticFormBuilder.inline_errors = :sentence
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 formtastic_changes.css stylesheet as well
46
- # Formtastic::SemanticFormBuilder.default_hint_class = "inline-hints"
47
- # Formtastic::SemanticFormBuilder.default_inline_error_class = "inline-errors"
48
- # Formtastic::SemanticFormBuilder.default_error_list_class = "errors"
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::SemanticFormBuilder.label_str_method = :humanize
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::SemanticFormBuilder.collection_label_methods = [
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: false. Overridden for specific fields by setting value to true,
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::SemanticFormBuilder.i18n_lookups_by_default = false
55
+ # Formtastic::FormBuilder.i18n_lookups_by_default = false
77
56
 
78
- # You can add custom inputs or override parts of Formtastic by subclassing SemanticFormBuilder and
79
- # specifying that class here. Defaults to SemanticFormBuilder.
80
- # Formtastic::SemanticFormHelper.builder = MyCustomBuilder
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]