formtastic 1.2.5 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +2 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG +279 -0
  5. data/Gemfile +3 -0
  6. data/README.textile +155 -172
  7. data/RELEASE_PROCESS +7 -0
  8. data/Rakefile +52 -0
  9. data/app/assets/stylesheets/formtastic.css +275 -0
  10. data/app/assets/stylesheets/formtastic_ie6.css +27 -0
  11. data/app/assets/stylesheets/formtastic_ie7.css +17 -0
  12. data/formtastic.gemspec +51 -0
  13. data/lib/formtastic.rb +21 -1960
  14. data/lib/formtastic/engine.rb +7 -0
  15. data/lib/formtastic/form_builder.rb +83 -0
  16. data/lib/formtastic/helpers.rb +16 -0
  17. data/lib/formtastic/helpers/buttons_helper.rb +277 -0
  18. data/lib/formtastic/helpers/errors_helper.rb +113 -0
  19. data/lib/formtastic/helpers/fieldset_wrapper.rb +75 -0
  20. data/lib/formtastic/helpers/file_column_detection.rb +16 -0
  21. data/lib/formtastic/helpers/form_helper.rb +198 -0
  22. data/lib/formtastic/helpers/input_helper.rb +366 -0
  23. data/lib/formtastic/helpers/inputs_helper.rb +392 -0
  24. data/lib/formtastic/helpers/reflection.rb +33 -0
  25. data/lib/formtastic/helpers/semantic_form_helper.rb +11 -0
  26. data/lib/formtastic/html_attributes.rb +21 -0
  27. data/lib/formtastic/i18n.rb +1 -0
  28. data/lib/formtastic/inputs.rb +31 -0
  29. data/lib/formtastic/inputs/base.rb +61 -0
  30. data/lib/formtastic/inputs/base/associations.rb +31 -0
  31. data/lib/formtastic/inputs/base/choices.rb +103 -0
  32. data/lib/formtastic/inputs/base/collections.rb +94 -0
  33. data/lib/formtastic/inputs/base/database.rb +17 -0
  34. data/lib/formtastic/inputs/base/errors.rb +58 -0
  35. data/lib/formtastic/inputs/base/fileish.rb +23 -0
  36. data/lib/formtastic/inputs/base/grouped_collections.rb +77 -0
  37. data/lib/formtastic/inputs/base/hints.rb +31 -0
  38. data/lib/formtastic/inputs/base/html.rb +52 -0
  39. data/lib/formtastic/inputs/base/labelling.rb +55 -0
  40. data/lib/formtastic/inputs/base/naming.rb +42 -0
  41. data/lib/formtastic/inputs/base/options.rb +18 -0
  42. data/lib/formtastic/inputs/base/stringish.rb +35 -0
  43. data/lib/formtastic/inputs/base/timeish.rb +128 -0
  44. data/lib/formtastic/inputs/base/validations.rb +166 -0
  45. data/lib/formtastic/inputs/base/wrapping.rb +40 -0
  46. data/lib/formtastic/inputs/boolean_input.rb +96 -0
  47. data/lib/formtastic/inputs/check_boxes_input.rb +179 -0
  48. data/lib/formtastic/inputs/country_input.rb +66 -0
  49. data/lib/formtastic/inputs/date_input.rb +14 -0
  50. data/lib/formtastic/inputs/datetime_input.rb +9 -0
  51. data/lib/formtastic/inputs/email_input.rb +40 -0
  52. data/lib/formtastic/inputs/file_input.rb +42 -0
  53. data/lib/formtastic/inputs/hidden_input.rb +66 -0
  54. data/lib/formtastic/inputs/number_input.rb +118 -0
  55. data/lib/formtastic/inputs/numeric_input.rb +21 -0
  56. data/lib/formtastic/inputs/password_input.rb +40 -0
  57. data/lib/formtastic/inputs/phone_input.rb +41 -0
  58. data/lib/formtastic/inputs/radio_input.rb +157 -0
  59. data/lib/formtastic/inputs/range_input.rb +119 -0
  60. data/lib/formtastic/inputs/search_input.rb +40 -0
  61. data/lib/formtastic/inputs/select_input.rb +210 -0
  62. data/lib/formtastic/inputs/string_input.rb +34 -0
  63. data/lib/formtastic/inputs/text_input.rb +47 -0
  64. data/lib/formtastic/inputs/time_input.rb +14 -0
  65. data/lib/formtastic/inputs/time_zone_input.rb +48 -0
  66. data/lib/formtastic/inputs/url_input.rb +40 -0
  67. data/lib/formtastic/localized_string.rb +105 -0
  68. data/lib/formtastic/railtie.rb +5 -7
  69. data/lib/formtastic/semantic_form_builder.rb +11 -0
  70. data/lib/formtastic/util.rb +6 -19
  71. data/lib/formtastic/version.rb +3 -0
  72. data/lib/generators/formtastic/install/install_generator.rb +28 -6
  73. data/lib/generators/templates/_form.html.erb +10 -4
  74. data/lib/generators/templates/_form.html.haml +8 -4
  75. data/lib/generators/templates/formtastic.rb +25 -32
  76. data/lib/locale/en.yml +1 -0
  77. data/lib/tasks/verify_rcov.rb +44 -0
  78. data/sample/basic_inputs.html +182 -0
  79. data/sample/config.ru +69 -0
  80. data/sample/index.html +14 -0
  81. data/spec/builder/custom_builder_spec.rb +109 -0
  82. data/spec/builder/error_proc_spec.rb +27 -0
  83. data/spec/builder/errors_spec.rb +193 -0
  84. data/spec/builder/semantic_fields_for_spec.rb +88 -0
  85. data/spec/helpers/buttons_helper_spec.rb +150 -0
  86. data/spec/helpers/commit_button_helper_spec.rb +470 -0
  87. data/spec/helpers/form_helper_spec.rb +135 -0
  88. data/spec/helpers/input_helper_spec.rb +837 -0
  89. data/spec/helpers/inputs_helper_spec.rb +562 -0
  90. data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
  91. data/spec/i18n_spec.rb +199 -0
  92. data/spec/inputs/boolean_input_spec.rb +184 -0
  93. data/spec/inputs/check_boxes_input_spec.rb +375 -0
  94. data/spec/inputs/country_input_spec.rb +133 -0
  95. data/spec/inputs/custom_input_spec.rb +52 -0
  96. data/spec/inputs/date_input_spec.rb +110 -0
  97. data/spec/inputs/datetime_input_spec.rb +115 -0
  98. data/spec/inputs/email_input_spec.rb +55 -0
  99. data/spec/inputs/file_input_spec.rb +59 -0
  100. data/spec/inputs/hidden_input_spec.rb +120 -0
  101. data/spec/inputs/include_blank_spec.rb +70 -0
  102. data/spec/inputs/label_spec.rb +104 -0
  103. data/spec/inputs/number_input_spec.rb +487 -0
  104. data/spec/inputs/numeric_input_spec.rb +41 -0
  105. data/spec/inputs/password_input_spec.rb +69 -0
  106. data/spec/inputs/phone_input_spec.rb +55 -0
  107. data/spec/inputs/placeholder_spec.rb +71 -0
  108. data/spec/inputs/radio_input_spec.rb +234 -0
  109. data/spec/inputs/range_input_spec.rb +477 -0
  110. data/spec/inputs/search_input_spec.rb +55 -0
  111. data/spec/inputs/select_input_spec.rb +545 -0
  112. data/spec/inputs/string_input_spec.rb +163 -0
  113. data/spec/inputs/text_input_spec.rb +158 -0
  114. data/spec/inputs/time_input_spec.rb +155 -0
  115. data/spec/inputs/time_zone_input_spec.rb +87 -0
  116. data/spec/inputs/url_input_spec.rb +55 -0
  117. data/spec/spec.opts +2 -0
  118. data/spec/spec_helper.rb +361 -0
  119. data/spec/support/custom_macros.rb +656 -0
  120. data/spec/support/deferred_garbage_collection.rb +21 -0
  121. data/spec/support/deprecation.rb +6 -0
  122. data/spec/support/test_environment.rb +30 -0
  123. metadata +306 -88
  124. data/generators/form/USAGE +0 -16
  125. data/generators/form/form_generator.rb +0 -111
  126. data/generators/formtastic/formtastic_generator.rb +0 -26
  127. data/init.rb +0 -5
  128. data/lib/formtastic/layout_helper.rb +0 -12
  129. data/lib/generators/formtastic/form/form_generator.rb +0 -84
  130. data/lib/generators/templates/formtastic.css +0 -145
  131. data/lib/generators/templates/formtastic_changes.css +0 -14
  132. data/lib/generators/templates/rails2/_form.html.erb +0 -5
  133. data/lib/generators/templates/rails2/_form.html.haml +0 -4
  134. data/rails/init.rb +0 -2
@@ -0,0 +1,40 @@
1
+ module Formtastic
2
+ module Inputs
3
+ module Base
4
+ # @todo relies on `dom_id`, `required?`, `optional`, `errors?`, `association_primary_key` & `sanitized_method_name` methods from another module
5
+ module Wrapping
6
+
7
+ # Override this method if you want to change the display order (for example, rendering the
8
+ # errors before the body of the input).
9
+ def input_wrapping(&block)
10
+ template.content_tag(:li,
11
+ [template.capture(&block), error_html, hint_html].join("\n").html_safe,
12
+ wrapper_html_options
13
+ )
14
+ end
15
+
16
+ def wrapper_html_options
17
+ opts = options[:wrapper_html] || {}
18
+ opts[:class] ||= []
19
+ opts[:class] = [opts[:class].to_s] unless opts[:class].is_a?(Array)
20
+ opts[:class] << as
21
+ opts[:class] << "input"
22
+ opts[:class] << "error" if errors?
23
+ opts[:class] << "optional" if optional?
24
+ opts[:class] << "required" if required?
25
+ opts[:class] << "autofocus" if autofocus?
26
+ opts[:class] = opts[:class].join(' ')
27
+
28
+ opts[:id] ||= wrapper_dom_id
29
+
30
+ opts
31
+ end
32
+
33
+ def wrapper_dom_id
34
+ @wrapper_dom_id ||= "#{dom_id.to_s.gsub((association_primary_key || method).to_s, sanitized_method_name.to_s)}_input"
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,96 @@
1
+ module Formtastic
2
+ module Inputs
3
+ # Boolean inputs are used to render an input for a single checkbox, typically for attributes
4
+ # with a simple yes/no or true/false value. Boolean inputs are used by default for boolean
5
+ # database columns.
6
+ #
7
+ # @example Full form context and markup
8
+ # <%= semantic_form_for @post %>
9
+ # <%= f.inputs do %>
10
+ # <%= f.input :published, :as => :boolean %>
11
+ # <% end %>
12
+ # <% end %>
13
+ #
14
+ # <form...>
15
+ # <fieldset>
16
+ # <ol>
17
+ # <li class="boolean" id="post_published_input">
18
+ # <input type="hidden" name="post[published]" id="post_published" value="0">
19
+ # <label for="post_published">
20
+ # <input type="checkbox" name="post[published]" id="post_published" value="1">
21
+ # Published?
22
+ # </label>
23
+ # </li>
24
+ # </ol>
25
+ # </fieldset>
26
+ # </form>
27
+ #
28
+ # @example Set the values for the checked and unchecked states
29
+ # <%= f.input :published, :checked_value => "yes", :unchecked_value => "no" %>
30
+ #
31
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
32
+ class BooleanInput
33
+ include Base
34
+
35
+ def to_html
36
+ input_wrapping do
37
+ hidden_field_html <<
38
+ label_with_nested_checkbox
39
+ end
40
+ end
41
+
42
+ def hidden_field_html
43
+ template.hidden_field_tag(input_html_options[:name], unchecked_value, :id => nil, :disabled => input_html_options[:disabled] )
44
+ end
45
+
46
+ def label_with_nested_checkbox
47
+ builder.label(
48
+ method,
49
+ label_text_with_embedded_checkbox,
50
+ label_html_options
51
+ )
52
+ end
53
+
54
+ def label_html_options
55
+ prev = super
56
+ prev[:class] = prev[:class] - ['label']
57
+
58
+ input_html_options.merge(
59
+ prev.merge(
60
+ :id => nil,
61
+ :for => input_html_options[:id]
62
+ )
63
+ )
64
+ end
65
+
66
+ def label_text_with_embedded_checkbox
67
+ label_text << " " << check_box_html
68
+ end
69
+
70
+ def check_box_html
71
+ template.check_box_tag("#{object_name}[#{method}]", checked_value, checked?, input_html_options)
72
+ end
73
+
74
+ def unchecked_value
75
+ options[:unchecked_value] || '0'
76
+ end
77
+
78
+ def checked_value
79
+ options[:checked_value] || '1'
80
+ end
81
+
82
+ def responds_to_global_required?
83
+ false
84
+ end
85
+
86
+ def input_html_options
87
+ {:name => "#{object_name}[#{method}]"}.merge(super)
88
+ end
89
+
90
+ def checked?
91
+ object && ActionView::Helpers::InstanceTag.check_box_checked?(object.send(method), checked_value)
92
+ end
93
+
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,179 @@
1
+ module Formtastic
2
+ module Inputs
3
+
4
+ # A CheckBoxes input is used to render a series of checkboxes. This is an alternative input choice
5
+ # for `has_many` or `has_and_belongs_to_many` associations like a `Post` belonging to many
6
+ # `categories` (by default, a {SelectInput `:select`} input is used, allowing multiple selections).
7
+ #
8
+ # Within the standard `<li>` wrapper, the output is a `<fieldset>` with a `<legend>` to
9
+ # represent the "label" for the input, and an `<ol>` containing `<li>`s for each choice in
10
+ # the association. Each `<li>` choice contains a hidden `<input>` tag for the "unchecked"
11
+ # value (like Rails), and a `<label>` containing the checkbox `<input>` and the label text
12
+ # for each choice.
13
+ #
14
+ # @example Basic example with full form context
15
+ #
16
+ # <%= semantic_form_for @post do |f| %>
17
+ # <%= f.inputs do %>
18
+ # <%= f.input :categories, :as => :check_boxes %>
19
+ # <% end %>
20
+ # <% end %>
21
+ #
22
+ # <li class='check_boxes'>
23
+ # <fieldset>
24
+ # <legend class="label"><label>Categories</label></legend>
25
+ # <ol>
26
+ # <li>
27
+ # <input type="hidden" name="post[category_ids][1]" value="">
28
+ # <label for="post_category_ids_1"><input id="post_category_ids_1" name="post[category_ids][1]" type="checkbox" value="1" /> Ruby</label>
29
+ # </li>
30
+ # <li>
31
+ # <input type="hidden" name="post[category_ids][2]" value="">
32
+ # <label for="post_category_ids_2"><input id="post_category_ids_2" name="post[category_ids][2]" type="checkbox" value="2" /> Rails</label>
33
+ # </li>
34
+ # </ol>
35
+ # </fieldset>
36
+ # </li>
37
+ #
38
+ # @example `:collection` can be used to customize the choices
39
+ # <%= f.input :categories, :as => :check_boxes, :collection => @categories %>
40
+ # <%= f.input :categories, :as => :check_boxes, :collection => Category.all %>
41
+ # <%= f.input :categories, :as => :check_boxes, :collection => Category.some_named_scope %>
42
+ # <%= f.input :categories, :as => :check_boxes, :collection => [Category.find_by_name("Ruby"), Category.find_by_name("Rails")] %>
43
+ # <%= f.input :categories, :as => :check_boxes, :collection => ["Ruby", "Rails"] %>
44
+ # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", "ruby"], ["Rails", "rails"]] %>
45
+ # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", "1"], ["Rails", "2"]] %>
46
+ # <%= f.input :categories, :as => :check_boxes, :collection => [["Ruby", 1], ["Rails", 2]] %>
47
+ # <%= f.input :categories, :as => :check_boxes, :collection => 1..5 %>
48
+ #
49
+ # @example `:hidden_fields` can be used to skip Rails' rendering of a hidden field before every checkbox
50
+ # <%= f.input :categories, :as => :check_boxes, :hidden_fields => false %>
51
+ #
52
+ # @example `:disabled` can be used to disable any checkboxes with a value found in the given Array
53
+ # <%= f.input :categories, :as => :check_boxes, :collection => ["a", "b"], :disabled => ["a"] %>
54
+ #
55
+ # @example `:member_label` can be used to call a different method (or a Proc) on each object in the collection for rendering the label text (it'll try the methods like `to_s` in `collection_label_methods` config by default)
56
+ # <%= f.input :categories, :as => :check_boxes, :member_label => :name %>
57
+ # <%= f.input :categories, :as => :check_boxes, :member_label => :name_with_post_count
58
+ # <%= f.input :categories, :as => :check_boxes, :member_label => { |c| "#{c.name} (#{pluralize("post", c.posts.count)})" }
59
+ #
60
+ # @example `:member_label` can be used with a helper method (both examples have the same result)
61
+ # <%= f.input :categories, :as => :check_boxes, :member_label => method(:fancy_label)
62
+ # <%= f.input :categories, :as => :check_boxes, :member_label => Proc.new { |category| fancy_label(category) }
63
+ #
64
+ # @example `:member_value` can be used to call a different method (or a Proc) on each object in the collection for rendering the value for each checkbox (it'll try the methods like `id` in `collection_value_methods` config by default)
65
+ # <%= f.input :categories, :as => :check_boxes, :member_value => :code %>
66
+ # <%= f.input :categories, :as => :check_boxes, :member_value => :isbn
67
+ # <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |c| c.name.downcase.underscore }
68
+ #
69
+ # @example `:member_value` can be used with a helper method (both examples have the same result)
70
+ # <%= f.input :categories, :as => :check_boxes, :member_value => method(:some_helper)
71
+ # <%= f.input :categories, :as => :check_boxes, :member_value => Proc.new { |category| some_helper(category) }
72
+ #
73
+ # @example `:value_as_class` can be used to add a class to the `<li>` wrapped around each choice using the checkbox value for custom styling of each choice
74
+ # <%= f.input :categories, :as => :check_boxes, :value_as_class => true %>
75
+ #
76
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
77
+ # @see Formtastic::Inputs::BooleanInput BooleanInput for a single checkbox for boolean (checked = true) inputs
78
+ #
79
+ # @todo Do/can we support the per-item HTML options like RadioInput?
80
+ class CheckBoxesInput
81
+ include Base
82
+ include Base::Collections
83
+ include Base::Choices
84
+
85
+ def to_html
86
+ input_wrapping do
87
+ choices_wrapping do
88
+ legend_html <<
89
+ hidden_field_for_all <<
90
+ choices_group_wrapping do
91
+ collection.map { |choice|
92
+ choice_wrapping(choice_wrapping_html_options(choice)) do
93
+ choice_html(choice)
94
+ end
95
+ }.join("\n").html_safe
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def choice_html(choice)
102
+ template.content_tag(:label,
103
+ hidden_fields? ?
104
+ check_box_with_hidden_input(choice) :
105
+ check_box_without_hidden_input(choice) <<
106
+ choice_label(choice),
107
+ label_html_options.merge(:for => choice_input_dom_id(choice))
108
+ )
109
+ end
110
+
111
+ def hidden_field_for_all
112
+ if hidden_fields?
113
+ ""
114
+ else
115
+ options = {}
116
+ options[:class] = [method.to_s.singularize, 'default'].join('_') if value_as_class?
117
+ options[:id] = [object_name, method, 'none'].join('_')
118
+ template.hidden_field_tag(input_name, '', options)
119
+ end
120
+ end
121
+
122
+ def hidden_fields?
123
+ options[:hidden_fields]
124
+ end
125
+
126
+ def check_box_with_hidden_input(choice)
127
+ value = choice_value(choice)
128
+ builder.check_box(
129
+ association_primary_key || method,
130
+ input_html_options.merge(:id => choice_input_dom_id(choice), :name => input_name, :disabled => disabled?(value)),
131
+ value,
132
+ unchecked_value
133
+ )
134
+ end
135
+
136
+ def check_box_without_hidden_input(choice)
137
+ value = choice_value(choice)
138
+ template.check_box_tag(
139
+ input_name,
140
+ value,
141
+ checked?(value),
142
+ input_html_options.merge(:id => choice_input_dom_id(choice), :disabled => disabled?(value))
143
+ )
144
+ end
145
+
146
+ def checked?(value)
147
+ selected_values.include?(value)
148
+ end
149
+
150
+ def disabled?(value)
151
+ disabled_values.include?(value)
152
+ end
153
+
154
+ def selected_values
155
+ if object.respond_to?(method)
156
+ selected_items = [object.send(method)].compact.flatten
157
+ [*selected_items.map { |o| send_or_call(value_method, o) }].compact
158
+ else
159
+ []
160
+ end
161
+ end
162
+
163
+ def disabled_values
164
+ vals = options[:disabled] || []
165
+ vals = [vals] unless vals.is_a?(Array)
166
+ vals
167
+ end
168
+
169
+ def unchecked_value
170
+ options[:unchecked_value] || ''
171
+ end
172
+
173
+ def input_name
174
+ "#{object_name}[#{association_primary_key || method}][]"
175
+ end
176
+
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,66 @@
1
+ module Formtastic
2
+ module Inputs
3
+ # Outputs a country select input, wrapping around a regular country_select helper.
4
+ # Rails doesn't come with a `country_select` helper by default any more, so you'll need to do
5
+ # one of the following:
6
+ #
7
+ # * install [the official Rails plugin](http://github.com/rails/iso-3166-country-select)
8
+ # * install any other country_select plugin that behaves in a similar way
9
+ # * roll your own `country_select` helper with the same args and options as the Rails one
10
+ #
11
+ # By default, Formtastic includes a handfull of English-speaking countries as "priority
12
+ # counties", which can be set in the `priority_countries` configuration array in the
13
+ # formtastic.rb initializer to suit your market and user base (see README for more info on
14
+ # configuration). Additionally, it is possible to set the :priority_countries on a per-input
15
+ # basis through the `:priority_countries` option. These priority countries will be passed down
16
+ # to the `country_select` helper of your choice, and may or may not be used by the helper.
17
+ #
18
+ # @example Basic example with full form context using `priority_countries` from config
19
+ #
20
+ # <%= semantic_form_for @user do |f| %>
21
+ # <%= f.inputs do %>
22
+ # <%= f.input :nationality, :as => :country %>
23
+ # <% end %>
24
+ # <% end %>
25
+ #
26
+ # <li class='country'>
27
+ # <label for="user_nationality">Country</label>
28
+ # <select id="user_nationality" name="user[nationality]">
29
+ # <option value="...">...</option>
30
+ # # ...
31
+ # </li>
32
+ #
33
+ # @example `:priority_countries` set on a specific input
34
+ #
35
+ # <%= semantic_form_for @user do |f| %>
36
+ # <%= f.inputs do %>
37
+ # <%= f.input :nationality, :as => :country, :priority_countries => ["Australia", "New Zealand"] %>
38
+ # <% end %>
39
+ # <% end %>
40
+ #
41
+ # <li class='country'>
42
+ # <label for="user_nationality">Country</label>
43
+ # <select id="user_nationality" name="user[nationality]">
44
+ # <option value="...">...</option>
45
+ # # ...
46
+ # </li>
47
+ #
48
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
49
+ class CountryInput
50
+ include Base
51
+
52
+ def to_html
53
+ raise "To use the :country input, please install a country_select plugin, like this one: http://github.com/rails/iso-3166-country-select" unless builder.respond_to?(:country_select)
54
+ input_wrapping do
55
+ label_html <<
56
+ builder.country_select(method, priority_countries, input_options, input_html_options)
57
+ end
58
+ end
59
+
60
+ def priority_countries
61
+ options[:priority_countries] || builder.priority_countries
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,14 @@
1
+ module Formtastic
2
+ module Inputs
3
+ # @see Formtastic::Inputs::Timeish Timeish module for documetation of date, time and datetime input options.
4
+ class DateInput
5
+ include Base
6
+ include Base::Timeish
7
+
8
+ # We don't want hour and minute fragments on a date input
9
+ def time_fragments
10
+ []
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Formtastic
2
+ module Inputs
3
+ # @see Formtastic::Inputs::Timeish Timeish module for documetation of date, time and datetime input options.
4
+ class DatetimeInput
5
+ include Base
6
+ include Base::Timeish
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,40 @@
1
+ module Formtastic
2
+ module Inputs
3
+
4
+ # Outputs a simple `<label>` with a HTML5 `<input type="email">` wrapped in the standard
5
+ # `<li>` wrapper. This is the default input choice for attributes with a name matching
6
+ # `/email/`, but can be applied to any text-like input with `:as => :email`.
7
+ #
8
+ # @example Full form context and output
9
+ #
10
+ # <%= semantic_form_for(@user) do |f| %>
11
+ # <%= f.inputs do %>
12
+ # <%= f.input :email_address, :as => :email %>
13
+ # <% end %>
14
+ # <% end %>
15
+ #
16
+ # <form...>
17
+ # <fieldset>
18
+ # <ol>
19
+ # <li class="email">
20
+ # <label for="user_email_address">Email address</label>
21
+ # <input type="email" id="user_email_address" name="user[email_address]">
22
+ # </li>
23
+ # </ol>
24
+ # </fieldset>
25
+ # </form>
26
+ #
27
+ # @see Formtastic::Helpers::InputsHelper#input InputsHelper#input for full documetation of all possible options.
28
+ class EmailInput
29
+ include Base
30
+ include Base::Stringish
31
+
32
+ def to_html
33
+ input_wrapping do
34
+ label_html <<
35
+ builder.email_field(method, input_html_options)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end