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
@@ -56,62 +56,8 @@ module Formtastic
56
56
  end
57
57
  end
58
58
 
59
- # Generates error messages for the given method, used for displaying errors right near the
60
- # field for data entry. Uses the `:inline_errors` config to determin the right presentation,
61
- # which may be an ordered list, a paragraph sentence containing all errors, or a paragraph
62
- # containing just the first error. If configred to `:none`, no error is shown.
63
- #
64
- # See the `:inline_errors` config documentation for more details.
65
- #
66
- # This method is mostly used internally, but can be used in your forms when creating your own
67
- # custom inputs, so it's been made public and aliased to `errors_on`.
68
- #
69
- # @example
70
- # <%= semantic_form_for @post do |f| %>
71
- # <li class='my-custom-text-input'>
72
- # <%= f.label(:body) %>
73
- # <%= f.text_field(:body) %>
74
- # <%= f.errors_on(:body) %>
75
- # </li>
76
- # <% end %>
77
- #
78
- # @deprecated See the README for the currently supported approach to custom inputs.
79
- def inline_errors_for(method, options = {})
80
- ActiveSupport::Deprecation.warn('inline_errors_for and errors_on are deprecated and will be removed on or after version 2.1', caller)
81
- if render_inline_errors?
82
- errors = error_keys(method, options).map{|x| @object.errors[x] }.flatten.compact.uniq
83
- send(:"error_#{inline_errors}", [*errors], options) if errors.any?
84
- else
85
- nil
86
- end
87
- end
88
- alias :errors_on :inline_errors_for
89
-
90
-
91
59
  protected
92
60
 
93
- # @deprecated This should be removed with inline_errors_for in 2.1
94
- def error_sentence(errors, options = {})
95
- error_class = options[:error_class] || default_inline_error_class
96
- template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.untaint), :class => error_class)
97
- end
98
-
99
- # @deprecated This should be removed with inline_errors_for in 2.1
100
- def error_list(errors, options = {})
101
- error_class = options[:error_class] || default_error_list_class
102
- list_elements = []
103
- errors.each do |error|
104
- list_elements << template.content_tag(:li, Formtastic::Util.html_safe(error.untaint))
105
- end
106
- template.content_tag(:ul, Formtastic::Util.html_safe(list_elements.join("\n")), :class => error_class)
107
- end
108
-
109
- # @deprecated This should be removed with inline_errors_for in 2.1
110
- def error_first(errors, options = {})
111
- error_class = options[:error_class] || default_inline_error_class
112
- template.content_tag(:p, Formtastic::Util.html_safe(errors.first.untaint), :class => error_class)
113
- end
114
-
115
61
  def error_keys(method, options)
116
62
  @methods_for_error ||= {}
117
63
  @methods_for_error[method] ||= begin
@@ -25,10 +25,6 @@ module Formtastic
25
25
  contents = args.last.is_a?(::Hash) ? '' : args.pop.flatten
26
26
  html_options = args.extract_options!
27
27
 
28
- legend = (html_options[:name] || '').to_s
29
- legend %= parent_child_index(html_options[:parent]) if html_options[:parent]
30
- legend = template.content_tag(:legend, template.content_tag(:span, Formtastic::Util.html_safe(legend))) unless legend.blank?
31
-
32
28
  if block_given?
33
29
  contents = if template.respond_to?(:is_haml?) && template.is_haml?
34
30
  template.capture_haml(&block)
@@ -39,6 +35,8 @@ module Formtastic
39
35
 
40
36
  # Ruby 1.9: String#to_s behavior changed, need to make an explicit join.
41
37
  contents = contents.join if contents.respond_to?(:join)
38
+
39
+ legend = field_set_legend(html_options)
42
40
  fieldset = template.content_tag(:fieldset,
43
41
  Formtastic::Util.html_safe(legend) << template.content_tag(:ol, Formtastic::Util.html_safe(contents)),
44
42
  html_options.except(:builder, :parent, :name)
@@ -47,6 +45,13 @@ module Formtastic
47
45
  fieldset
48
46
  end
49
47
 
48
+ def field_set_legend(html_options)
49
+ legend = (html_options[:name] || '').to_s
50
+ legend %= parent_child_index(html_options[:parent]) if html_options[:parent]
51
+ legend = template.content_tag(:legend, template.content_tag(:span, Formtastic::Util.html_safe(legend))) unless legend.blank?
52
+ legend
53
+ end
54
+
50
55
  # Gets the nested_child_index value from the parent builder. It returns a hash with each
51
56
  # association that the parent builds.
52
57
  def parent_child_index(parent) #:nodoc:
@@ -72,4 +77,4 @@ module Formtastic
72
77
 
73
78
  end
74
79
  end
75
- end
80
+ end
@@ -144,7 +144,7 @@ module Formtastic
144
144
  options[:builder] ||= @@builder
145
145
  options[:html] ||= {}
146
146
  options[:html][:novalidate] = !@@builder.perform_browser_validations unless options[:html].key?(:novalidate)
147
- @@builder.custom_namespace = options[:namespace].to_s
147
+ @@builder.custom_namespace = options.delete(:namespace).to_s
148
148
 
149
149
  singularizer = defined?(ActiveModel::Naming.singular) ? ActiveModel::Naming.method(:singular) : ActionController::RecordIdentifier.method(:singular_class_name)
150
150
 
@@ -169,7 +169,7 @@ module Formtastic
169
169
  def semantic_fields_for(record_name, record_object = nil, options = {}, &block)
170
170
  options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
171
171
  options[:builder] ||= @@builder
172
- @@builder.custom_namespace = options[:namespace].to_s # TODO needed?
172
+ @@builder.custom_namespace = options.delete(:namespace).to_s # TODO needed?
173
173
 
174
174
  with_custom_field_error_proc do
175
175
  self.fields_for(record_name, record_object, options, &block)
@@ -140,15 +140,9 @@ module Formtastic
140
140
  # @option options :member_label [Symbol, Proc, Method]
141
141
  # Override the method called on each object in the `:collection` for use as the `<label>` content (`:check_boxes` & `:radio` inputs) or `<option>` content (`:select` inputs)
142
142
  #
143
- # @option options :label_method [Symbol, Proc, Method]
144
- # Deprecated, renamed to :member_label
145
- #
146
143
  # @option options :member_value [Symbol, Proc, Method]
147
144
  # Override the method called on each object in the `:collection` for use as the `value` attribute in the `<input>` (`:check_boxes` & `:radio` inputs) or `<option>` (`:select` inputs)
148
145
  #
149
- # @option options :value_method [Symbol, Proc, Method]
150
- # Deprecated, renamed to :member_value
151
- #
152
146
  # @option options :hint_class [String]
153
147
  # Override the `class` attribute applied to the `<p>` tag used when a `:hint` is rendered for an input
154
148
  #
@@ -164,9 +158,6 @@ module Formtastic
164
158
  # @option options :find_options [Symbol]
165
159
  # TODO will probably be deprecated
166
160
  #
167
- # @option options :group_label_method [Symbol]
168
- # Deprecated, use `:group_label`
169
- #
170
161
  # @option options :group_label [Symbol]
171
162
  # TODO will probably be deprecated
172
163
  #
@@ -177,7 +168,7 @@ module Formtastic
177
168
  # Specify the text in the first ('blank') `:select` input `<option>` to prompt a user to make a selection (implicitly sets `:include_blank` to `true`)
178
169
  #
179
170
  # @todo Can we kill `:hint_class` & `:error_class`? What's the use case for input-by-input? Shift to config or burn!
180
- # @todo Can we kill `:group_by` & `:group_label`/`:group_label_method`? Should be done with :collection => grouped_options_for_select(...)
171
+ # @todo Can we kill `:group_by` & `:group_label`? Should be done with :collection => grouped_options_for_select(...)
181
172
  # @todo Can we kill `:find_options`? Should be done with MyModel.some_scope.where(...).order(...).whatever_scope
182
173
  # @todo Can we kill `:label`, `:hint` & `:prompt`? All strings could be shifted to i18n!
183
174
  #
@@ -300,7 +300,7 @@ module Formtastic
300
300
  end
301
301
 
302
302
  out = template.content_tag(:li, out, :class => "input") if wrap_it
303
- @already_in_an_inputs_block = false
303
+ @already_in_an_inputs_block = wrap_it
304
304
  out
305
305
  end
306
306
 
@@ -351,7 +351,10 @@ module Formtastic
351
351
 
352
352
  # Collects content columns (non-relation columns) for the current form object class.
353
353
  def content_columns #:nodoc:
354
- model_name.constantize.content_columns.collect { |c| c.name.to_sym }.compact rescue []
354
+ # TODO: NameError is raised by Inflector.constantize. Consider checking if it exists instead.
355
+ begin klass = model_name.constantize; rescue NameError; return [] end
356
+ return [] unless klass.respond_to?(:content_columns)
357
+ klass.content_columns.collect { |c| c.name.to_sym }.compact
355
358
  end
356
359
 
357
360
  # Deals with :for option when it's supplied to inputs methods. Additional
@@ -397,4 +400,4 @@ module Formtastic
397
400
 
398
401
  end
399
402
  end
400
- end
403
+ end
@@ -8,10 +8,11 @@ module Formtastic
8
8
  DEFAULT_VALUES = YAML.load_file(File.expand_path("../../locale/en.yml", __FILE__))["en"]["formtastic"].freeze
9
9
  SCOPES = [
10
10
  '%{model}.%{nested_model}.%{action}.%{attribute}',
11
- '%{model}.%{action}.%{attribute}',
12
11
  '%{model}.%{nested_model}.%{attribute}',
13
- '%{model}.%{attribute}',
12
+ '%{nested_model}.%{action}.%{attribute}',
14
13
  '%{nested_model}.%{attribute}',
14
+ '%{model}.%{action}.%{attribute}',
15
+ '%{model}.%{attribute}',
15
16
  '%{attribute}'
16
17
  ]
17
18
 
@@ -12,11 +12,12 @@ module Formtastic
12
12
  @method = method
13
13
  @options = options.dup
14
14
 
15
- warn_and_correct_option!(:label_method, :member_label)
16
- warn_and_correct_option!(:value_method, :member_value)
17
- warn_and_correct_option!(:group_label_method, :group_label)
15
+ removed_option!(:label_method)
16
+ removed_option!(:value_method)
17
+ removed_option!(:group_label_method)
18
18
  end
19
19
 
20
+ # Usefull for deprecating options.
20
21
  def warn_and_correct_option!(old_option_name, new_option_name)
21
22
  if options.key?(old_option_name)
22
23
  ::ActiveSupport::Deprecation.warn("The :#{old_option_name} option is deprecated in favour of :#{new_option_name} and will be removed from Formtastic after 2.0")
@@ -24,6 +25,11 @@ module Formtastic
24
25
  end
25
26
  end
26
27
 
28
+ # Usefull for raising an error on previously supported option.
29
+ def removed_option!(old_option_name)
30
+ raise ArgumentError, ":#{old_option_name} is no longer available" if options.key?(old_option_name)
31
+ end
32
+
27
33
  extend ActiveSupport::Autoload
28
34
 
29
35
  autoload :Associations
@@ -37,7 +43,9 @@ module Formtastic
37
43
  autoload :Html
38
44
  autoload :Labelling
39
45
  autoload :Naming
46
+ autoload :Numeric
40
47
  autoload :Options
48
+ autoload :Placeholder
41
49
  autoload :Stringish
42
50
  autoload :Timeish
43
51
  autoload :Validations
@@ -44,7 +44,11 @@ module Formtastic
44
44
  end
45
45
 
46
46
  def choice_label(choice)
47
- choice.is_a?(Array) ? choice.first : choice
47
+ if choice.is_a?(Array)
48
+ choice.first
49
+ else
50
+ choice
51
+ end.to_s
48
52
  end
49
53
 
50
54
  def choice_value(choice)
@@ -71,6 +75,7 @@ module Formtastic
71
75
  [
72
76
  builder.custom_namespace,
73
77
  sanitized_object_name,
78
+ builder.options[:index],
74
79
  association_primary_key || method,
75
80
  choice_html_safe_value(choice)
76
81
  ].compact.reject { |i| i.blank? }.join("_")
@@ -4,14 +4,26 @@ module Formtastic
4
4
  module Collections
5
5
 
6
6
  def label_method
7
- label_and_value_method(raw_collection).first
7
+ @label_method ||= (label_method_from_options || label_and_value_method.first)
8
+ end
9
+
10
+ def label_method_from_options
11
+ options[:member_label]
8
12
  end
9
13
 
10
14
  def value_method
11
- label_and_value_method(raw_collection).last
15
+ @value_method ||= (value_method_from_options || label_and_value_method.last)
16
+ end
17
+
18
+ def value_method_from_options
19
+ options[:member_value]
12
20
  end
13
21
 
14
- def label_and_value_method(_collection, grouped=false)
22
+ def label_and_value_method
23
+ @label_and_value_method ||= label_and_value_method_from_collection(raw_collection)
24
+ end
25
+
26
+ def label_and_value_method_from_collection(_collection)
15
27
  sample = _collection.first || _collection.last
16
28
 
17
29
  case sample
@@ -19,13 +31,13 @@ module Formtastic
19
31
  label, value = :first, :last
20
32
  when Integer
21
33
  label, value = :to_s, :to_i
22
- when String, NilClass
34
+ when Symbol, String, NilClass
23
35
  label, value = :to_s, :to_s
24
36
  end
25
37
 
26
38
  # Order of preference: user supplied method, class defaults, auto-detect
27
- label = (grouped ? options[:grouped_label_method] : options[:member_label]) || label || builder.collection_label_methods.find { |m| sample.respond_to?(m) }
28
- value = (grouped ? options[:grouped_value_method] : options[:member_value]) || value || builder.collection_value_methods.find { |m| sample.respond_to?(m) }
39
+ label ||= builder.collection_label_methods.find { |m| sample.respond_to?(m) }
40
+ value ||= builder.collection_value_methods.find { |m| sample.respond_to?(m) }
29
41
 
30
42
  [label, value]
31
43
  end
@@ -40,7 +52,7 @@ module Formtastic
40
52
 
41
53
  # Return if we have an Array of strings, fixnums or arrays
42
54
  return raw_collection if (raw_collection.instance_of?(Array) || raw_collection.instance_of?(Range)) &&
43
- [Array, Fixnum, String, Symbol].include?(raw_collection.first.class) &&
55
+ [Array, Fixnum, String].include?(raw_collection.first.class) &&
44
56
  !(options.include?(:member_label) || options.include?(:member_value))
45
57
 
46
58
  raw_collection.map { |o| [send_or_call(label_method, o), send_or_call(value_method, o)] }
@@ -48,24 +60,35 @@ module Formtastic
48
60
 
49
61
  def collection_from_options
50
62
  items = options[:collection]
51
- items = items.to_a if items.is_a?(Hash)
52
- items
63
+ case items
64
+ when Hash
65
+ items.to_a
66
+ when Range
67
+ items.to_a.collect{ |c| [c.to_s, c] }
68
+ else
69
+ items
70
+ end
53
71
  end
54
72
 
55
73
  def collection_from_association
56
74
  if reflection
57
- raise PolymorphicInputWithoutCollectionError.new("A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations.") if reflection.options && reflection.options[:polymorphic] == true
75
+ if reflection.respond_to?(:options)
76
+ raise PolymorphicInputWithoutCollectionError.new(
77
+ "A collection must be supplied for #{method} input. Collections cannot be guessed for polymorphic associations."
78
+ ) if reflection.options[:polymorphic] == true
79
+ end
58
80
 
59
81
  find_options_from_options = options[:find_options] || {}
60
82
  conditions_from_options = find_options_from_options[:conditions] || {}
61
- conditions_from_reflection = reflection.options && reflection.options[:conditions] || {}
83
+ conditions_from_reflection = (reflection.respond_to?(:options) && reflection.options[:conditions]) || {}
62
84
  conditions_from_reflection = conditions_from_reflection.call if conditions_from_reflection.is_a?(Proc)
63
85
 
86
+ scope_conditions = conditions_from_reflection.empty? ? nil : {:conditions => conditions_from_reflection}
64
87
  if conditions_from_options.any?
65
- reflection.klass.scoped(:conditions => conditions_from_reflection).where(conditions_from_options)
88
+ reflection.klass.scoped(scope_conditions).where(conditions_from_options)
66
89
  else
67
90
  find_options_from_options.merge!(:include => group_by) if self.respond_to?(:group_by) && group_by
68
- reflection.klass.scoped(:conditions => conditions_from_reflection).where(find_options_from_options)
91
+ reflection.klass.scoped(scope_conditions).where(find_options_from_options)
69
92
  end
70
93
  end
71
94
  end
@@ -20,7 +20,7 @@ module Formtastic
20
20
  end
21
21
 
22
22
  def group_label_method_from_grouped_collection
23
- label_and_value_method(raw_grouped_collection, true).first
23
+ label_and_value_method_from_collection(raw_grouped_collection).first
24
24
  end
25
25
 
26
26
  def group_association
@@ -0,0 +1,50 @@
1
+ module Formtastic
2
+ module Inputs
3
+ module Base
4
+ module Numeric
5
+ def input_html_options
6
+ defaults = super
7
+
8
+ # override rails default size - not valid on numeric inputs
9
+ #@todo document/spec
10
+ defaults[:size] = nil
11
+
12
+ if in_option
13
+ defaults[:min] = in_option.to_a.min
14
+ defaults[:max] = in_option.to_a.max
15
+ else
16
+ defaults[:min] ||= min_option
17
+ defaults[:max] ||= max_option
18
+ end
19
+ defaults[:step] ||= step_option
20
+ defaults
21
+ end
22
+
23
+ def step_option
24
+ return options[:step] if options.key?(:step)
25
+ validation_step
26
+ end
27
+
28
+ def min_option
29
+ return options[:min] if options.key?(:min)
30
+ validation_min
31
+ end
32
+
33
+ def max_option
34
+ return options[:max] if options.key?(:max)
35
+ validation_max
36
+ end
37
+
38
+ def in_option
39
+ options[:in]
40
+ end
41
+
42
+ def wrapper_html_options
43
+ new_class = [super[:class], "numeric", "stringish"].compact.join(" ")
44
+ super.merge(:class => new_class)
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -8,7 +8,7 @@ module Formtastic
8
8
  end
9
9
 
10
10
  def formtastic_options
11
- [:priority_countries, :priority_zones, :value_method, :label_method, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :label_html, :value_as_class, :find_options, :class]
11
+ [:priority_countries, :priority_zones, :member_label, :member_value, :collection, :required, :label, :as, :hint, :input_html, :label_html, :value_as_class, :find_options, :class]
12
12
  end
13
13
 
14
14
  end
@@ -0,0 +1,17 @@
1
+ module Formtastic
2
+ module Inputs
3
+ module Base
4
+ module Placeholder
5
+
6
+ def input_html_options
7
+ {:placeholder => placeholder_text}.merge(super)
8
+ end
9
+
10
+ def placeholder_text
11
+ localized_string(method, options[:placeholder], :placeholder)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,7 +2,7 @@ module Formtastic
2
2
  module Inputs
3
3
  module Base
4
4
  module Stringish
5
-
5
+
6
6
  # @abstract Override this method in your input class to describe how the input should render itself.
7
7
  def to_html
8
8
  input_wrapping do
@@ -15,15 +15,10 @@ module Formtastic
15
15
  def input_html_options
16
16
  {
17
17
  :maxlength => options[:input_html].try(:[], :maxlength) || limit,
18
- :size => builder.default_text_field_size,
19
- :placeholder => placeholder_text
18
+ :size => builder.default_text_field_size
20
19
  }.merge(super)
21
20
  end
22
21
 
23
- def placeholder_text
24
- localized_string(method, options[:placeholder], :placeholder)
25
- end
26
-
27
22
  def wrapper_html_options
28
23
  new_class = [super[:class], "stringish"].compact.join(" ")
29
24
  super.merge(:class => new_class)