formtastic 2.0.2 → 2.1.0.beta1

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 (116) hide show
  1. data/.gitignore +4 -1
  2. data/Appraisals +11 -0
  3. data/CHANGELOG +2 -2
  4. data/Gemfile +0 -2
  5. data/README.textile +183 -151
  6. data/Rakefile +9 -5
  7. data/app/assets/stylesheets/formtastic.css +16 -3
  8. data/formtastic.gemspec +6 -2
  9. data/gemfiles/rails-3.0.gemfile +7 -0
  10. data/gemfiles/rails-3.1.gemfile +7 -0
  11. data/gemfiles/rails-3.2.gemfile +7 -0
  12. data/lib/formtastic.rb +10 -2
  13. data/lib/formtastic/actions.rb +11 -0
  14. data/lib/formtastic/actions/base.rb +156 -0
  15. data/lib/formtastic/actions/button_action.rb +72 -0
  16. data/lib/formtastic/actions/buttonish.rb +17 -0
  17. data/lib/formtastic/actions/input_action.rb +68 -0
  18. data/lib/formtastic/actions/link_action.rb +87 -0
  19. data/lib/formtastic/engine.rb +5 -1
  20. data/lib/formtastic/form_builder.rb +3 -0
  21. data/lib/formtastic/helpers.rb +2 -1
  22. data/lib/formtastic/helpers/action_helper.rb +109 -0
  23. data/lib/formtastic/helpers/actions_helper.rb +168 -0
  24. data/lib/formtastic/helpers/buttons_helper.rb +22 -9
  25. data/lib/formtastic/helpers/errors_helper.rb +0 -54
  26. data/lib/formtastic/helpers/fieldset_wrapper.rb +10 -5
  27. data/lib/formtastic/helpers/form_helper.rb +2 -2
  28. data/lib/formtastic/helpers/input_helper.rb +1 -10
  29. data/lib/formtastic/helpers/inputs_helper.rb +6 -3
  30. data/lib/formtastic/i18n.rb +3 -2
  31. data/lib/formtastic/inputs/base.rb +11 -3
  32. data/lib/formtastic/inputs/base/choices.rb +6 -1
  33. data/lib/formtastic/inputs/base/collections.rb +36 -13
  34. data/lib/formtastic/inputs/base/grouped_collections.rb +1 -1
  35. data/lib/formtastic/inputs/base/numeric.rb +50 -0
  36. data/lib/formtastic/inputs/base/options.rb +1 -1
  37. data/lib/formtastic/inputs/base/placeholder.rb +17 -0
  38. data/lib/formtastic/inputs/base/stringish.rb +2 -7
  39. data/lib/formtastic/inputs/base/timeish.rb +21 -5
  40. data/lib/formtastic/inputs/base/validations.rb +1 -1
  41. data/lib/formtastic/inputs/base/wrapping.rb +10 -3
  42. data/lib/formtastic/inputs/boolean_input.rb +10 -2
  43. data/lib/formtastic/inputs/check_boxes_input.rb +18 -9
  44. data/lib/formtastic/inputs/country_input.rb +2 -2
  45. data/lib/formtastic/inputs/date_input.rb +19 -1
  46. data/lib/formtastic/inputs/datetime_input.rb +1 -1
  47. data/lib/formtastic/inputs/email_input.rb +2 -1
  48. data/lib/formtastic/inputs/file_input.rb +1 -1
  49. data/lib/formtastic/inputs/hidden_input.rb +1 -1
  50. data/lib/formtastic/inputs/number_input.rb +6 -36
  51. data/lib/formtastic/inputs/password_input.rb +2 -1
  52. data/lib/formtastic/inputs/phone_input.rb +3 -2
  53. data/lib/formtastic/inputs/radio_input.rb +1 -1
  54. data/lib/formtastic/inputs/range_input.rb +8 -32
  55. data/lib/formtastic/inputs/search_input.rb +2 -1
  56. data/lib/formtastic/inputs/select_input.rb +56 -28
  57. data/lib/formtastic/inputs/string_input.rb +3 -1
  58. data/lib/formtastic/inputs/text_input.rb +5 -4
  59. data/lib/formtastic/inputs/time_input.rb +4 -8
  60. data/lib/formtastic/inputs/time_zone_input.rb +1 -1
  61. data/lib/formtastic/inputs/url_input.rb +2 -1
  62. data/lib/formtastic/localized_string.rb +6 -94
  63. data/lib/formtastic/localizer.rb +110 -0
  64. data/lib/formtastic/version.rb +1 -1
  65. data/lib/generators/formtastic/form/form_generator.rb +105 -0
  66. data/lib/generators/templates/_form.html.erb +2 -2
  67. data/lib/generators/templates/_form.html.haml +4 -4
  68. data/lib/generators/templates/_form.html.slim +2 -2
  69. data/lib/generators/templates/formtastic.rb +4 -0
  70. data/lib/locale/en.yml +2 -0
  71. data/sample/basic_inputs.html +22 -0
  72. data/spec/actions/button_action_spec.rb +63 -0
  73. data/spec/actions/generic_action_spec.rb +484 -0
  74. data/spec/actions/input_action_spec.rb +59 -0
  75. data/spec/actions/link_action_spec.rb +92 -0
  76. data/spec/builder/semantic_fields_for_spec.rb +14 -0
  77. data/spec/generators/formtastic/form/form_generator_spec.rb +118 -0
  78. data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
  79. data/spec/helpers/action_helper_spec.rb +365 -0
  80. data/spec/helpers/actions_helper_spec.rb +143 -0
  81. data/spec/helpers/buttons_helper_spec.rb +39 -23
  82. data/spec/helpers/commit_button_helper_spec.rb +153 -93
  83. data/spec/helpers/inputs_helper_spec.rb +14 -0
  84. data/spec/i18n_spec.rb +11 -0
  85. data/spec/inputs/boolean_input_spec.rb +31 -2
  86. data/spec/inputs/check_boxes_input_spec.rb +29 -1
  87. data/spec/inputs/date_input_spec.rb +95 -0
  88. data/spec/inputs/datetime_input_spec.rb +49 -0
  89. data/spec/inputs/email_input_spec.rb +28 -0
  90. data/spec/inputs/file_input_spec.rb +28 -0
  91. data/spec/inputs/hidden_input_spec.rb +28 -0
  92. data/spec/inputs/include_blank_spec.rb +53 -45
  93. data/spec/inputs/number_input_spec.rb +34 -4
  94. data/spec/inputs/password_input_spec.rb +28 -0
  95. data/spec/inputs/phone_input_spec.rb +28 -0
  96. data/spec/inputs/placeholder_spec.rb +10 -10
  97. data/spec/inputs/radio_input_spec.rb +51 -6
  98. data/spec/inputs/range_input_spec.rb +30 -2
  99. data/spec/inputs/search_input_spec.rb +27 -0
  100. data/spec/inputs/select_input_spec.rb +52 -6
  101. data/spec/inputs/string_input_spec.rb +28 -0
  102. data/spec/inputs/text_input_spec.rb +27 -0
  103. data/spec/inputs/time_input_spec.rb +67 -1
  104. data/spec/inputs/time_zone_input_spec.rb +28 -0
  105. data/spec/inputs/url_input_spec.rb +28 -0
  106. data/spec/inputs/with_options_spec.rb +43 -0
  107. data/spec/spec_helper.rb +22 -6
  108. data/spec/support/custom_macros.rb +6 -134
  109. data/spec/support/test_environment.rb +0 -1
  110. metadata +104 -17
  111. data/lib/formtastic/helpers/semantic_form_helper.rb +0 -11
  112. data/lib/formtastic/inputs/numeric_input.rb +0 -21
  113. data/lib/formtastic/railtie.rb +0 -12
  114. data/lib/formtastic/semantic_form_builder.rb +0 -11
  115. data/spec/builder/errors_spec.rb +0 -203
  116. data/spec/inputs/numeric_input_spec.rb +0 -41
@@ -25,10 +25,12 @@ module Formtastic
25
25
  # </fieldset>
26
26
  # </form>
27
27
  #
28
- # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
28
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
29
29
  class StringInput
30
30
  include Base
31
31
  include Base::Stringish
32
+ include Base::Placeholder
33
+
32
34
  end
33
35
  end
34
36
  end
@@ -9,24 +9,25 @@ module Formtastic
9
9
  #
10
10
  # <%= semantic_form_for(@user) do |f| %>
11
11
  # <%= f.inputs do %>
12
- # <%= f.input :first_name, :as => :string %>
12
+ # <%= f.input :first_name, :as => :text %>
13
13
  # <% end %>
14
14
  # <% end %>
15
15
  #
16
16
  # <form...>
17
17
  # <fieldset>
18
18
  # <ol>
19
- # <li class="string">
19
+ # <li class="text">
20
20
  # <label for="user_first_name">First name</label>
21
- # <input type="text" id="user_first_name" name="user[first_name]">
21
+ # <textarea cols="30" id="user_first_name" name="user[first_name]" rows="20"></textarea>
22
22
  # </li>
23
23
  # </ol>
24
24
  # </fieldset>
25
25
  # </form>
26
26
  #
27
- # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
27
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
28
28
  class TextInput
29
29
  include Base
30
+ include Base::Placeholder
30
31
 
31
32
  def input_html_options
32
33
  {
@@ -5,7 +5,7 @@ module Formtastic
5
5
  # well, defaulting to `Time.current` if the form object doesn't have a value, much like Rails'
6
6
  # own `time_select`.
7
7
  #
8
- # @see Formtastic::Inputs::Timeish Timeish module for documetation of date, time and datetime input options.
8
+ # @see Formtastic::Inputs::Base::Timeish Timeish module for documentation of date, time and datetime input options.
9
9
  class TimeInput
10
10
  include Base
11
11
  include Base::Timeish
@@ -15,18 +15,14 @@ module Formtastic
15
15
  time_fragments
16
16
  end
17
17
 
18
- def value_or_default_value
19
- value ? value : Time.current
20
- end
21
-
22
18
  def fragment_value(fragment)
23
- value_or_default_value.send(fragment)
19
+ value ? value.send(fragment) : ""
24
20
  end
25
21
 
26
22
  def hidden_fragments
27
23
  if !options[:ignore_date]
28
24
  date_fragments.map do |fragment|
29
- template.hidden_field_tag("#{object_name}[#{fragment_name(fragment)}]", fragment_value(fragment), :id => fragment_id(fragment), :disabled => input_html_options[:disabled] )
25
+ template.hidden_field_tag(hidden_field_name(fragment), fragment_value(fragment), :id => fragment_id(fragment), :disabled => input_html_options[:disabled] )
30
26
  end.join.html_safe
31
27
  else
32
28
  super
@@ -35,4 +31,4 @@ module Formtastic
35
31
 
36
32
  end
37
33
  end
38
- end
34
+ end
@@ -26,7 +26,7 @@ module Formtastic
26
26
  # </fieldset>
27
27
  # </form>
28
28
  #
29
- # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
29
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
30
30
  #
31
31
  # @todo document :priority_zones option
32
32
  # @todo configurable default :priority_zones?
@@ -24,10 +24,11 @@ module Formtastic
24
24
  # </fieldset>
25
25
  # </form>
26
26
  #
27
- # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
27
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documentation of all possible options.
28
28
  class UrlInput
29
29
  include Base
30
30
  include Base::Stringish
31
+ include Base::Placeholder
31
32
 
32
33
  def to_html
33
34
  input_wrapping do
@@ -1,105 +1,17 @@
1
1
  module Formtastic
2
- # @private
3
2
  module LocalizedString
4
3
 
5
- protected
6
-
7
- # Internal generic method for looking up localized values within Formtastic
8
- # using I18n, if no explicit value is set and I18n-lookups are enabled.
9
- #
10
- # Enabled/Disable this by setting:
11
- #
12
- # Formtastic::FormBuilder.i18n_lookups_by_default = true/false
13
- #
14
- # Lookup priority:
15
- #
16
- # 'formtastic.%{type}.%{model}.%{action}.%{attribute}'
17
- # 'formtastic.%{type}.%{model}.%{attribute}'
18
- # 'formtastic.%{type}.%{attribute}'
19
- #
20
- # Example:
21
- #
22
- # 'formtastic.labels.post.edit.title'
23
- # 'formtastic.labels.post.title'
24
- # 'formtastic.labels.title'
25
- #
26
- # NOTE: Generic, but only used for form input titles/labels/hints/actions (titles = legends, actions = buttons).
27
- #
28
- def localized_string(key, value, type, options = {}) #:nodoc:
29
- key = value if value.is_a?(::Symbol)
30
-
31
- if value.is_a?(::String)
32
- escape_html_entities(value)
33
- else
34
- use_i18n = value.nil? ? i18n_lookups_by_default : (value != false)
35
-
36
- if use_i18n
37
- model_name, nested_model_name = normalize_model_name(self.model_name.underscore)
38
-
39
- action_name = template.params[:action].to_s rescue ''
40
- attribute_name = key.to_s
41
-
42
- defaults = Formtastic::I18n::SCOPES.reject do |i18n_scope|
43
- nested_model_name.nil? && i18n_scope.match(/nested_model/)
44
- end.collect do |i18n_scope|
45
- i18n_path = i18n_scope.dup
46
- i18n_path.gsub!('%{action}', action_name)
47
- i18n_path.gsub!('%{model}', model_name)
48
- i18n_path.gsub!('%{nested_model}', nested_model_name) unless nested_model_name.nil?
49
- i18n_path.gsub!('%{attribute}', attribute_name)
50
- i18n_path.gsub!('..', '.')
51
- i18n_path.to_sym
52
- end
53
- defaults << ''
54
-
55
- defaults.uniq!
56
-
57
- default_key = defaults.shift
58
- i18n_value = Formtastic::I18n.t(default_key,
59
- options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
60
- i18n_value = i18n_value.is_a?(::String) ? i18n_value : nil
61
- if i18n_value.blank? && type == :label
62
- # This is effectively what Rails label helper does for i18n lookup
63
- options[:scope] = [:helpers, type]
64
- options[:default] = defaults
65
- i18n_value = ::I18n.t(default_key, options)
66
- end
67
- (i18n_value.is_a?(::String) && i18n_value.present?) ? escape_html_entities(i18n_value) : nil
68
- end
69
- end
70
- end
71
-
72
4
  def model_name
73
5
  @object.present? ? @object.class.name : @object_name.to_s.classify
74
6
  end
75
7
 
76
- def normalize_model_name(name)
77
- if !name =~ /\[/ && self.respond_to?(:builder) && builder.respond_to?(:parent_builder) && builder.parent_builder.object_name
78
- # Rails 3.1 nested builder case
79
- [builder.parent_builder.object_name.to_s, name]
80
- elsif name =~ /(.+)\[(.+)\]/
81
- # Rails 3 (and 3.1?) nested builder case with :post rather than @post
82
- [$1, $2]
83
- elsif self.respond_to?(:builder) && builder.respond_to?(:options) && builder.options.key?(:parent_builder)
84
- # Rails 3.0 nested builder work-around case, where :parent_builder is provided by f.semantic_form_for
85
- [builder.options[:parent_builder].object_name.to_s, name]
86
- else
87
- # Non-nested case
88
- [name]
89
- end
90
- end
91
-
92
- def escape_html_entities(string) #:nodoc:
93
- if (respond_to?(:builder) && builder.escape_html_entities_in_hints_and_labels) ||
94
- (self.respond_to?(:escape_html_entities_in_hints_and_labels) && escape_html_entities_in_hints_and_labels)
95
- string = template.escape_once(string) unless string.respond_to?(:html_safe?) && string.html_safe? == true # Acceppt html_safe flag as indicator to skip escaping
96
- end
97
- string
98
- end
8
+ protected
99
9
 
100
- def i18n_lookups_by_default
101
- respond_to?(:builder) ? builder.i18n_lookups_by_default : i18n_lookups_by_default
10
+ def localized_string(key, value, type, options = {}) #:nodoc:
11
+ current_builder = respond_to?(:builder) ? builder : self
12
+ localizer = Formtastic::FormBuilder.i18n_localizer.new(current_builder)
13
+ localizer.localize(key, value, type, options)
102
14
  end
103
15
 
104
16
  end
105
- end
17
+ end
@@ -0,0 +1,110 @@
1
+ module Formtastic
2
+ # Implementation for looking up localized values within Formtastic using I18n, if no
3
+ # explicit value (like the `:label` option) is set and I18n-lookups are enabled in the
4
+ # configuration.
5
+ #
6
+ # You can subclass this to implement your own Localizer, and configure Formtastic to use this
7
+ # localizer with:
8
+ #
9
+ # Formtastic::FormBuilder.i18n_localizer
10
+ #
11
+ # Enabled/disable i18n lookups completely with:
12
+ #
13
+ # Formtastic::FormBuilder.i18n_lookups_by_default = true/false
14
+ #
15
+ # Lookup priority:
16
+ #
17
+ # 'formtastic.%{type}.%{model}.%{action}.%{attribute}'
18
+ # 'formtastic.%{type}.%{model}.%{attribute}'
19
+ # 'formtastic.%{type}.%{attribute}'
20
+ #
21
+ # Example:
22
+ #
23
+ # 'formtastic.labels.post.edit.title'
24
+ # 'formtastic.labels.post.title'
25
+ # 'formtastic.labels.title'
26
+ class Localizer
27
+
28
+ attr_accessor :builder
29
+
30
+ def initialize(current_builder)
31
+ self.builder = current_builder
32
+ end
33
+
34
+ def localize(key, value, type, options = {}) #:nodoc:
35
+ key = value if value.is_a?(::Symbol)
36
+
37
+ if value.is_a?(::String)
38
+ escape_html_entities(value)
39
+ else
40
+ use_i18n = value.nil? ? i18n_lookups_by_default : (value != false)
41
+
42
+ if use_i18n
43
+ model_name, nested_model_name = normalize_model_name(builder.model_name.underscore)
44
+
45
+ action_name = builder.template.params[:action].to_s rescue ''
46
+ attribute_name = key.to_s
47
+
48
+
49
+ defaults = Formtastic::I18n::SCOPES.reject do |i18n_scope|
50
+ nested_model_name.nil? && i18n_scope.match(/nested_model/)
51
+ end.collect do |i18n_scope|
52
+ i18n_path = i18n_scope.dup
53
+ i18n_path.gsub!('%{action}', action_name)
54
+ i18n_path.gsub!('%{model}', model_name)
55
+ i18n_path.gsub!('%{nested_model}', nested_model_name) unless nested_model_name.nil?
56
+ i18n_path.gsub!('%{attribute}', attribute_name)
57
+ i18n_path.gsub!('..', '.')
58
+ i18n_path.to_sym
59
+ end
60
+ defaults << ''
61
+
62
+ defaults.uniq!
63
+
64
+ default_key = defaults.shift
65
+ i18n_value = Formtastic::I18n.t(default_key,
66
+ options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
67
+ i18n_value = i18n_value.is_a?(::String) ? i18n_value : nil
68
+ if i18n_value.blank? && type == :label
69
+ # This is effectively what Rails label helper does for i18n lookup
70
+ options[:scope] = [:helpers, type]
71
+ options[:default] = defaults
72
+ i18n_value = ::I18n.t(default_key, options)
73
+ end
74
+ (i18n_value.is_a?(::String) && i18n_value.present?) ? escape_html_entities(i18n_value) : nil
75
+ end
76
+ end
77
+ end
78
+
79
+ protected
80
+
81
+ def normalize_model_name(name)
82
+ if !name =~ /\[/ && builder.respond_to?(:parent_builder) && builder.parent_builder.object_name
83
+ # Rails 3.1 nested builder case
84
+ [builder.parent_builder.object_name.to_s, name]
85
+ elsif name =~ /(.+)\[(.+)\]/
86
+ # Rails 3 (and 3.1?) nested builder case with :post rather than @post
87
+ [$1, $2]
88
+ elsif builder.respond_to?(:options) && builder.options.key?(:parent_builder)
89
+ # Rails 3.0 nested builder work-around case, where :parent_builder is provided by f.semantic_form_for
90
+ [builder.options[:parent_builder].object_name.to_s, name]
91
+ else
92
+ # Non-nested case
93
+ [name]
94
+ end
95
+ end
96
+
97
+ def escape_html_entities(string) #:nodoc:
98
+ if (builder.escape_html_entities_in_hints_and_labels) ||
99
+ (self.respond_to?(:escape_html_entities_in_hints_and_labels) && escape_html_entities_in_hints_and_labels)
100
+ string = builder.template.escape_once(string) unless string.respond_to?(:html_safe?) && string.html_safe? == true # Accept html_safe flag as indicator to skip escaping
101
+ end
102
+ string
103
+ end
104
+
105
+ def i18n_lookups_by_default
106
+ builder.i18n_lookups_by_default
107
+ end
108
+
109
+ end
110
+ end
@@ -1,3 +1,3 @@
1
1
  module Formtastic
2
- VERSION = "2.0.2"
2
+ VERSION = "2.1.0.beta1"
3
3
  end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
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
+ # $ rails generate formtastic:form Post
8
+ # @example Copy the partial code to the pasteboard rather than generating a partial
9
+ # $ rails generate formtastic:form Post --copy
10
+ # @example Return HAML output instead of default template engine
11
+ # $ rails generate formtastic:form Post --haml
12
+ # @example Generate a form for specific model attributes
13
+ # $ rails generate formtastic:form Post title:string body:text
14
+ # @example Generate a form for a specific controller
15
+ # $ rails generate formtastic:form Post --controller admin/posts
16
+ class FormGenerator < Rails::Generators::NamedBase
17
+ desc "Generates a Formtastic form partial based on an existing model."
18
+
19
+ argument :name, :type => :string, :required => true, :banner => 'MODEL_NAME'
20
+ argument :attributes, :type => :array, :default => [], :banner => 'attribute attribute'
21
+
22
+ source_root File.expand_path('../../../templates', __FILE__)
23
+
24
+ class_option :template_engine
25
+
26
+ class_option :copy, :type => :boolean, :default => false, :group => :formtastic,
27
+ :desc => 'Copy the generated code the clipboard instead of generating a partial file."'
28
+
29
+ class_option :controller, :type => :string, :default => false, :group => :formtastic,
30
+ :desc => 'Generate for custom controller/view path - in case model and controller namespace is different, i.e. "admin/posts"'
31
+
32
+ def create_or_show
33
+ @attributes = reflected_attributes if @attributes.empty?
34
+
35
+ engine = options[:template_engine]
36
+
37
+ if options[:copy]
38
+ template = File.read("#{self.class.source_root}/_form.html.#{engine}")
39
+ erb = ERB.new(template, nil, '-')
40
+ generated_code = erb.result(binding).strip rescue nil
41
+ puts "The following code has been copied to the clipboard, just paste it in your views:" if save_to_clipboard(generated_code)
42
+ puts generated_code || "Error: Nothing generated. Does the model exist?"
43
+ else
44
+ empty_directory "app/views/#{controller_path}"
45
+ template "_form.html.#{engine}", "app/views/#{controller_path}/_form.html.#{engine}"
46
+ end
47
+ end
48
+
49
+ protected
50
+
51
+ def controller_path
52
+ @controller_path ||= if options[:controller]
53
+ options[:controller].underscore
54
+ else
55
+ name.underscore.pluralize
56
+ end
57
+ end
58
+
59
+ def reflected_attributes
60
+ columns = content_columns
61
+ columns += association_columns
62
+ end
63
+
64
+ def model
65
+ @model ||= name.camelize.constantize
66
+ end
67
+
68
+ # Collects content columns (non-relation columns) for the current class.
69
+ # Skips Active Record Timestamps.
70
+ def content_columns
71
+ model.content_columns.select do |column|
72
+ !Formtastic::Helpers::InputsHelper::SKIPPED_COLUMNS.include? column.name.to_sym
73
+ end
74
+ end
75
+
76
+ # Collects association columns (relation columns) for the current class. Skips polymorphic
77
+ # associations because we can't guess which class to use for an automatically generated input.
78
+ def association_columns
79
+ model.reflect_on_all_associations(:belongs_to).select do |association_reflection|
80
+ association_reflection.options[:polymorphic] != true
81
+ end
82
+ end
83
+
84
+ def save_to_clipboard(data)
85
+ return unless data
86
+
87
+ begin
88
+ case RUBY_PLATFORM
89
+ when /win32/
90
+ require 'win32/clipboard'
91
+ ::Win32::Clipboard.data = data
92
+ when /darwin/ # mac
93
+ `echo "#{data}" | pbcopy`
94
+ else # linux/unix
95
+ `echo "#{data}" | xsel --clipboard` || `echo "#{data}" | xclip`
96
+ end
97
+ rescue LoadError
98
+ false
99
+ else
100
+ true
101
+ end
102
+ end
103
+
104
+ end
105
+ end
@@ -5,7 +5,7 @@
5
5
  <%- end -%>
6
6
  <%% end %>
7
7
 
8
- <%%= f.buttons do %>
9
- <%%= f.commit_button %>
8
+ <%%= f.actions do %>
9
+ <%%= f.action(:submit, :as => :input) %>
10
10
  <%% end %>
11
11
  <%% end %>