generic_form_for 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. data/.document +5 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +123 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.textile +217 -0
  8. data/Rakefile +52 -0
  9. data/VERSION +1 -0
  10. data/generic_form_for.gemspec +232 -0
  11. data/generic_form_for.tmproj +166 -0
  12. data/lib/generators/generic_form_for/form_builder/form_builder_generator.rb +16 -0
  13. data/lib/generators/generic_form_for/form_builder/templates/form_builder.erb +37 -0
  14. data/lib/generators/generic_form_for/form_builder/templates/helper.erb +15 -0
  15. data/lib/generators/generic_form_for/install/install_generator.rb +20 -0
  16. data/lib/generators/generic_form_for/install/templates/_form.html.erb +11 -0
  17. data/lib/generators/generic_form_for/install/templates/_form.html.haml +8 -0
  18. data/lib/generators/generic_form_for/install/templates/form_for.en.yml +11 -0
  19. data/lib/generators/generic_form_for/install/templates/initializer.rb +5 -0
  20. data/lib/generic_form_for.rb +22 -0
  21. data/lib/generic_form_for/actions.rb +10 -0
  22. data/lib/generic_form_for/actions/base.rb +63 -0
  23. data/lib/generic_form_for/actions/base/icon.rb +24 -0
  24. data/lib/generic_form_for/actions/button_action.rb +14 -0
  25. data/lib/generic_form_for/actions/input_action.rb +11 -0
  26. data/lib/generic_form_for/engine.rb +11 -0
  27. data/lib/generic_form_for/form_builder.rb +111 -0
  28. data/lib/generic_form_for/helpers.rb +10 -0
  29. data/lib/generic_form_for/helpers/action_helper.rb +52 -0
  30. data/lib/generic_form_for/helpers/actions_helper.rb +35 -0
  31. data/lib/generic_form_for/helpers/fieldset_helper.rb +48 -0
  32. data/lib/generic_form_for/helpers/form_helper.rb +64 -0
  33. data/lib/generic_form_for/helpers/input_helper.rb +77 -0
  34. data/lib/generic_form_for/i18n.rb +44 -0
  35. data/lib/generic_form_for/inputs.rb +22 -0
  36. data/lib/generic_form_for/inputs/base.rb +98 -0
  37. data/lib/generic_form_for/inputs/base/error_message.rb +30 -0
  38. data/lib/generic_form_for/inputs/base/hint.rb +28 -0
  39. data/lib/generic_form_for/inputs/base/label.rb +42 -0
  40. data/lib/generic_form_for/inputs/base/number.rb +18 -0
  41. data/lib/generic_form_for/inputs/base/placeholder.rb +20 -0
  42. data/lib/generic_form_for/inputs/base/string.rb +17 -0
  43. data/lib/generic_form_for/inputs/base/validations.rb +42 -0
  44. data/lib/generic_form_for/inputs/boolean_input.rb +35 -0
  45. data/lib/generic_form_for/inputs/email_input.rb +19 -0
  46. data/lib/generic_form_for/inputs/file_input.rb +13 -0
  47. data/lib/generic_form_for/inputs/hidden_input.rb +23 -0
  48. data/lib/generic_form_for/inputs/number_input.rb +20 -0
  49. data/lib/generic_form_for/inputs/password_input.rb +13 -0
  50. data/lib/generic_form_for/inputs/phone_input.rb +19 -0
  51. data/lib/generic_form_for/inputs/range_input.rb +19 -0
  52. data/lib/generic_form_for/inputs/search_input.rb +19 -0
  53. data/lib/generic_form_for/inputs/select_input.rb +32 -0
  54. data/lib/generic_form_for/inputs/string_input.rb +13 -0
  55. data/lib/generic_form_for/inputs/text_input.rb +20 -0
  56. data/lib/generic_form_for/inputs/url_input.rb +19 -0
  57. data/sample_app/.gitignore +15 -0
  58. data/sample_app/Gemfile +15 -0
  59. data/sample_app/Gemfile.lock +130 -0
  60. data/sample_app/README.rdoc +261 -0
  61. data/sample_app/Rakefile +7 -0
  62. data/sample_app/app/assets/images/rails.png +0 -0
  63. data/sample_app/app/assets/javascripts/application.js +14 -0
  64. data/sample_app/app/assets/javascripts/posts.js.coffee +3 -0
  65. data/sample_app/app/assets/javascripts/samples.js.coffee +3 -0
  66. data/sample_app/app/assets/stylesheets/application.css +14 -0
  67. data/sample_app/app/assets/stylesheets/posts.css.scss +3 -0
  68. data/sample_app/app/assets/stylesheets/samples.css.scss +3 -0
  69. data/sample_app/app/assets/stylesheets/scaffolds.css.scss +56 -0
  70. data/sample_app/app/controllers/application_controller.rb +3 -0
  71. data/sample_app/app/controllers/samples_controller.rb +83 -0
  72. data/sample_app/app/form_builders/sample_form_builder.rb +17 -0
  73. data/sample_app/app/helpers/application_helper.rb +2 -0
  74. data/sample_app/app/helpers/sample_form_builder_helper.rb +15 -0
  75. data/sample_app/app/helpers/samples_helper.rb +2 -0
  76. data/sample_app/app/mailers/.gitkeep +0 -0
  77. data/sample_app/app/models/.gitkeep +0 -0
  78. data/sample_app/app/models/sample.rb +29 -0
  79. data/sample_app/app/views/layouts/application.html.erb +16 -0
  80. data/sample_app/app/views/samples/_form.html.erb +49 -0
  81. data/sample_app/app/views/samples/edit.html.erb +6 -0
  82. data/sample_app/app/views/samples/index.html.erb +21 -0
  83. data/sample_app/app/views/samples/new.html.erb +5 -0
  84. data/sample_app/app/views/samples/show.html.erb +5 -0
  85. data/sample_app/config.ru +4 -0
  86. data/sample_app/config/application.rb +65 -0
  87. data/sample_app/config/boot.rb +6 -0
  88. data/sample_app/config/database.yml +25 -0
  89. data/sample_app/config/environment.rb +5 -0
  90. data/sample_app/config/environments/development.rb +37 -0
  91. data/sample_app/config/environments/production.rb +67 -0
  92. data/sample_app/config/environments/test.rb +37 -0
  93. data/sample_app/config/initializers/backtrace_silencers.rb +7 -0
  94. data/sample_app/config/initializers/generic_form_for.rb +5 -0
  95. data/sample_app/config/initializers/inflections.rb +15 -0
  96. data/sample_app/config/initializers/mime_types.rb +5 -0
  97. data/sample_app/config/initializers/secret_token.rb +7 -0
  98. data/sample_app/config/initializers/session_store.rb +8 -0
  99. data/sample_app/config/initializers/wrap_parameters.rb +14 -0
  100. data/sample_app/config/locales/en.yml +22 -0
  101. data/sample_app/config/locales/form_for.en.yml +13 -0
  102. data/sample_app/config/routes.rb +61 -0
  103. data/sample_app/db/migrate/20120203082117_create_samples.rb +22 -0
  104. data/sample_app/db/schema.rb +36 -0
  105. data/sample_app/db/seeds.rb +7 -0
  106. data/sample_app/lib/assets/.gitkeep +0 -0
  107. data/sample_app/lib/tasks/.gitkeep +0 -0
  108. data/sample_app/lib/templates/erb/scaffold/_form.html.erb +11 -0
  109. data/sample_app/log/.gitkeep +0 -0
  110. data/sample_app/public/404.html +26 -0
  111. data/sample_app/public/422.html +26 -0
  112. data/sample_app/public/500.html +25 -0
  113. data/sample_app/public/favicon.ico +0 -0
  114. data/sample_app/public/robots.txt +5 -0
  115. data/sample_app/script/rails +6 -0
  116. data/sample_app/vendor/assets/javascripts/.gitkeep +0 -0
  117. data/sample_app/vendor/assets/stylesheets/.gitkeep +0 -0
  118. data/sample_app/vendor/plugins/.gitkeep +0 -0
  119. data/spec/actions/base/icon_spec.rb +38 -0
  120. data/spec/actions/button_action_spec.rb +43 -0
  121. data/spec/actions/input_action_spec.rb +66 -0
  122. data/spec/helpers/action_helper_spec.rb +32 -0
  123. data/spec/helpers/actions_helper_spec.rb +60 -0
  124. data/spec/helpers/fieldset_helper_spec.rb +83 -0
  125. data/spec/helpers/form_helper_spec.rb +101 -0
  126. data/spec/helpers/input_helper_spec.rb +66 -0
  127. data/spec/i18n_spec.rb +46 -0
  128. data/spec/inputs/base/error_message_spec.rb +86 -0
  129. data/spec/inputs/base/hint_spec.rb +77 -0
  130. data/spec/inputs/base/label_spec.rb +99 -0
  131. data/spec/inputs/base/number_spec.rb +32 -0
  132. data/spec/inputs/base/placeholder_spec.rb +32 -0
  133. data/spec/inputs/base/string_spec.rb +25 -0
  134. data/spec/inputs/base/validations_spec.rb +53 -0
  135. data/spec/inputs/base_spec.rb +69 -0
  136. data/spec/inputs/boolean_input_spec.rb +95 -0
  137. data/spec/inputs/email_input_spec.rb +30 -0
  138. data/spec/inputs/file_input_spec.rb +30 -0
  139. data/spec/inputs/hidden_input_spec.rb +30 -0
  140. data/spec/inputs/number_input_spec.rb +37 -0
  141. data/spec/inputs/password_input_spec.rb +30 -0
  142. data/spec/inputs/phone_input_spec.rb +30 -0
  143. data/spec/inputs/range_input_spec.rb +37 -0
  144. data/spec/inputs/search_input_spec.rb +30 -0
  145. data/spec/inputs/select_input_spec.rb +51 -0
  146. data/spec/inputs/string_input_spec.rb +115 -0
  147. data/spec/inputs/text_input_spec.rb +30 -0
  148. data/spec/inputs/url_input_spec.rb +30 -0
  149. data/spec/spec_helper.rb +122 -0
  150. metadata +374 -0
@@ -0,0 +1,22 @@
1
+ module GenericFormFor
2
+ # @private
3
+ module Inputs
4
+ autoload :Base, 'generic_form_for/inputs/base'
5
+ autoload :StringInput, 'generic_form_for/inputs/string_input'
6
+ autoload :PasswordInput, 'generic_form_for/inputs/password_input'
7
+ autoload :BooleanInput, 'generic_form_for/inputs/boolean_input'
8
+ autoload :SelectInput, 'generic_form_for/inputs/select_input'
9
+ # autoload :RadioInput, 'generic_form_for/inputs/radio_input'
10
+ # autoload :CheckBoxesInput, 'generic_form_for/inputs/check_boxes_input'
11
+ autoload :TextInput, 'generic_form_for/inputs/text_input'
12
+ autoload :HiddenInput, 'generic_form_for/inputs/hidden_input'
13
+ autoload :EmailInput, 'generic_form_for/inputs/email_input'
14
+ autoload :PhoneInput, 'generic_form_for/inputs/phone_input'
15
+ autoload :UrlInput, 'generic_form_for/inputs/url_input'
16
+ autoload :SearchInput, 'generic_form_for/inputs/search_input'
17
+ autoload :NumberInput, 'generic_form_for/inputs/number_input'
18
+ autoload :RangeInput, 'generic_form_for/inputs/range_input'
19
+ autoload :FileInput, 'generic_form_for/inputs/file_input'
20
+ # autoload :DateInput, 'generic_form_for/inputs/date_input'
21
+ end
22
+ end
@@ -0,0 +1,98 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ include I18n
5
+
6
+ def wrap_in(*args, &block)
7
+ wrap_options = args.first.is_a?(Hash) ? args.pop : {}
8
+ wrap_options[:class] = [@first_wrapper_class, *wrap_options[:class], *(options[:wrapper_html]||{})[:class]].join(' ').strip
9
+ wrap_options.merge!((options.delete(:wrapper_html) || {}).except(:class))
10
+ @first_wrapper_class = nil
11
+ template.concat( template.content_tag(wrap_options.delete(:tag) || :div, wrap_options) do
12
+ template.capture(&block) if block_given?
13
+ end.html_safe)
14
+ end
15
+
16
+ attr_accessor :builder, :template, :object, :object_name, :method, :column, :options
17
+
18
+ def initialize(builder, template, object, object_name, method, column, options)
19
+ @builder = builder
20
+ @template = template
21
+ @object = object
22
+ @object_name = object_name
23
+ @method = method
24
+ @column = column
25
+ @options = options.dup
26
+ @first_wrapper_class = "#{options[:as]}-input"
27
+ end
28
+
29
+ def to_html
30
+ instance_exec &builder.input_wrapper_proc
31
+ ""
32
+ end
33
+
34
+ def merge_html_options(runtime_options,config_options)
35
+ runtime_options[:class] = [*runtime_options[:class], *config_options[:class]].compact.join(' ').strip
36
+ config_options.merge(runtime_options)
37
+ end
38
+
39
+ def input_html_options
40
+ default_input_options.merge(options[:html] || {}).merge(input_options)
41
+ end
42
+ #
43
+ def default_input_options
44
+ {
45
+ :autofocus => autofocus?,
46
+ :required => required?,
47
+ :class => input_html_class
48
+ }
49
+ end
50
+
51
+ def input_html_class
52
+ ([options[:as]] + [*options[:class]] + [('errors' if errors?)]).compact.join(" ").strip
53
+ end
54
+
55
+ def input_options
56
+ options.except(*form_builder_options)
57
+ end
58
+
59
+ def form_builder_options
60
+ [:collection, :required, :label, :as, :hint, :wrapper_html, :label_html, :error_html, :class, :autofocus]
61
+ end
62
+
63
+ def autofocus?
64
+ if options.key?(:autofocus)
65
+ if options[:autofocus]
66
+ template.autofocus = false
67
+ true
68
+ else
69
+ false
70
+ end
71
+ else
72
+ return false unless template.autofocus
73
+ template.autofocus = false
74
+ true
75
+ end
76
+ end
77
+
78
+ extend ActiveSupport::Autoload
79
+ #
80
+ autoload :Placeholder
81
+ autoload :String
82
+ autoload :Number
83
+ #
84
+ autoload :Hint
85
+ include Hint
86
+
87
+ autoload :Validations
88
+ include Validations
89
+
90
+ autoload :Label
91
+ include Label
92
+
93
+ autoload :ErrorMessage
94
+ include ErrorMessage
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,30 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module ErrorMessage
5
+
6
+ def error_html(config_options={})
7
+ template.concat(render_error? ? template.content_tag(:span, errors.join(", "), error_html_options(config_options)) : "")
8
+ end
9
+
10
+ def error_html_options(config_options={})
11
+ opts = (options[:error_html] || {}).dup
12
+ opts[:class] = ["error", *opts[:class], *config_options[:class]].compact.join(' ').strip
13
+ config_options.merge(opts)
14
+ end
15
+
16
+ def errors
17
+ @errors ||= object.respond_to?(:errors) ? object.errors[method.to_s] : []
18
+ end
19
+
20
+ def errors?
21
+ !errors.empty?
22
+ end
23
+
24
+ def render_error?
25
+ errors?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module Hint
5
+
6
+ def hint_html(config_options={})
7
+ return "" unless render_hint?
8
+ template.concat template.content_tag(config_options.delete(:tag) || :p, hint_text, hint_html_options(config_options))
9
+ end
10
+
11
+ def hint_html_options(config_options={})
12
+ opts = (options[:hint_html] || {}).dup
13
+ opts[:class] = [*opts[:class], *config_options[:class]].compact.join(' ').strip
14
+ config_options.merge(opts)
15
+ end
16
+
17
+ def render_hint?
18
+ options.key?(:hint)
19
+ end
20
+
21
+ def hint_text
22
+ render_hint? ? translate_hint(options[:hint]) : ""
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,42 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module Label
5
+
6
+ def label_html(config_options={})
7
+ return unless render_label?
8
+ template.concat builder.label(method, label_text, label_html_options(config_options))
9
+ end
10
+
11
+ def label_html_options(config_options={})
12
+ opts = (options[:label_html] || {}).dup
13
+ opts[:for] ||= options[:id]
14
+ opts[:class] = [*opts[:class], *config_options[:class]].compact.join(' ').strip
15
+ config_options.merge(opts)
16
+ end
17
+
18
+ def label_text
19
+ (translated_label << requirement_text).html_safe
20
+ end
21
+
22
+ def requirement_text
23
+ return "" unless required?
24
+ if builder.required_string.respond_to?(:call)
25
+ builder.required_string.call
26
+ else
27
+ builder.required_string
28
+ end
29
+ end
30
+
31
+ def translated_label
32
+ translate_label(options[:label] || method)
33
+ end
34
+
35
+ def render_label?
36
+ !(options[:label] == false)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module Number
5
+ include Placeholder
6
+
7
+ def input_html_options
8
+ {
9
+ :step => decimals,
10
+ :min => minimal_number,
11
+ :max => maximal_number
12
+ }.merge(super)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module Placeholder
5
+
6
+ def input_html_options
7
+ # merge it on top of everything
8
+ super.merge({
9
+ :placeholder => placeholder_text
10
+ })
11
+ end
12
+
13
+ def placeholder_text
14
+ translate_placeholder(options[:placeholder])
15
+ end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module String
5
+ include Placeholder
6
+
7
+ def input_html_options
8
+ {
9
+ :maxlength => limit,
10
+ :size => builder.default_text_field_size
11
+ }.merge(super)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,42 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ module Base
4
+ module Validations
5
+
6
+ def required?
7
+ options.key?(:required) ? options[:required] : required_from_validations?
8
+ end
9
+
10
+ def required_from_validations?
11
+ @required_from_validations ||= object.class.validators_on(method).any? { |v| v.kind_of? ActiveModel::Validations::PresenceValidator } if object.class.respond_to?(:validators_on)
12
+ end
13
+
14
+ def limits_from_validations
15
+ @limits_from_validations ||= object.class.validators_on(method).map { |v| v.options if v.kind_of? ActiveModel::Validations::NumericalityValidator }.compact.first if object.class.respond_to?(:validators_on)
16
+ end
17
+
18
+ def minimal_number
19
+ return nil unless min = limits_from_validations
20
+ min[:greater_than_or_equal_to] || (min[:greater_than] ? min[:greater_than] + decimals.to_f : nil)
21
+ end
22
+
23
+
24
+ def maximal_number
25
+ return nil unless max = limits_from_validations
26
+ max[:less_than_or_equal_to] || (max[:less_than] ? max[:less_than] - decimals.to_f : nil)
27
+ end
28
+
29
+ def limit
30
+ column.try(:limit)
31
+ end
32
+
33
+ def decimals
34
+ return 1 if column.try(:type) == :integer
35
+ scale = column.try(:scale).to_f
36
+ scale == 0 ? nil : "0.#{"0"*(scale-1)}1"
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ class BooleanInput
4
+ include Base
5
+
6
+ def input_html_options
7
+ {:checked => checked?}.merge(super).except(*[:checked_value, :unchecked_value, :value])
8
+ end
9
+
10
+ def input_html(config_options={})
11
+ template.concat builder.check_box(method, merge_html_options(input_html_options,config_options), checked_value, unchecked_value)
12
+ end
13
+
14
+ def unchecked_value
15
+ options[:unchecked_value] || '0'
16
+ end
17
+
18
+ def checked_value
19
+ options[:checked_value] || '1'
20
+ end
21
+
22
+ def checked?
23
+ if options.key?(:value)
24
+ return checked_value.to_s == options[:value].to_s
25
+ end
26
+ return false unless object.respond_to?(method)
27
+ checked_value.to_s == object.send(method).to_s
28
+ end
29
+
30
+ def required?
31
+ false
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ class EmailInput
4
+ include Base
5
+ include String
6
+
7
+ def input_html_options
8
+ {
9
+ :type => "email"
10
+ }.merge(super)
11
+ end
12
+
13
+ def input_html(config_options={})
14
+ template.concat builder.text_field(method, merge_html_options(input_html_options,config_options))
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ class FileInput
4
+ include Base
5
+ include Placeholder
6
+
7
+ def input_html(config_options={})
8
+ template.concat builder.file_field(method, merge_html_options(input_html_options,config_options))
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ class HiddenInput
4
+ include Base
5
+
6
+ def input_html(config_options={})
7
+ template.concat builder.hidden_field(method, merge_html_options(input_html_options,config_options))
8
+ end
9
+
10
+ def render_label?
11
+ false
12
+ end
13
+
14
+ def render_error?
15
+ false
16
+ end
17
+
18
+ def render_hint?
19
+ false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module GenericFormFor
2
+ module Inputs
3
+ class NumberInput
4
+ include Base
5
+ include Number
6
+
7
+ def input_html_options
8
+ {
9
+ :type => "number",
10
+ :size => nil
11
+ }.merge(super)
12
+ end
13
+
14
+ def input_html(config_options={})
15
+ template.concat builder.text_field(method, merge_html_options(input_html_options,config_options))
16
+ end
17
+
18
+ end
19
+ end
20
+ end