formtastic 2.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +4 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +105 -0
  8. data/MIT-LICENSE +1 -1
  9. data/{README.textile → README.md} +204 -219
  10. data/RELEASE_PROCESS +3 -1
  11. data/Rakefile +27 -29
  12. data/app/assets/stylesheets/formtastic.css +3 -2
  13. data/bin/appraisal +8 -0
  14. data/formtastic.gemspec +11 -14
  15. data/gemfiles/rails_5.2/Gemfile +5 -0
  16. data/gemfiles/rails_6.0/Gemfile +5 -0
  17. data/gemfiles/rails_6.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +18 -0
  20. data/lib/formtastic/actions/button_action.rb +55 -60
  21. data/lib/formtastic/actions/input_action.rb +59 -57
  22. data/lib/formtastic/actions/link_action.rb +68 -67
  23. data/lib/formtastic/actions.rb +6 -3
  24. data/lib/formtastic/deprecation.rb +5 -0
  25. data/lib/formtastic/engine.rb +3 -1
  26. data/lib/formtastic/form_builder.rb +35 -16
  27. data/lib/formtastic/helpers/action_helper.rb +34 -28
  28. data/lib/formtastic/helpers/enum.rb +13 -0
  29. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  30. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
  31. data/lib/formtastic/helpers/form_helper.rb +19 -16
  32. data/lib/formtastic/helpers/input_helper.rb +69 -97
  33. data/lib/formtastic/helpers/inputs_helper.rb +35 -25
  34. data/lib/formtastic/helpers/reflection.rb +4 -4
  35. data/lib/formtastic/helpers.rb +1 -2
  36. data/lib/formtastic/html_attributes.rb +12 -1
  37. data/lib/formtastic/i18n.rb +1 -1
  38. data/lib/formtastic/input_class_finder.rb +18 -0
  39. data/lib/formtastic/inputs/base/choices.rb +2 -2
  40. data/lib/formtastic/inputs/base/collections.rb +46 -14
  41. data/lib/formtastic/inputs/base/database.rb +7 -2
  42. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  43. data/lib/formtastic/inputs/base/errors.rb +7 -7
  44. data/lib/formtastic/inputs/base/hints.rb +2 -2
  45. data/lib/formtastic/inputs/base/html.rb +10 -9
  46. data/lib/formtastic/inputs/base/labelling.rb +5 -8
  47. data/lib/formtastic/inputs/base/naming.rb +4 -4
  48. data/lib/formtastic/inputs/base/numeric.rb +1 -1
  49. data/lib/formtastic/inputs/base/options.rb +3 -4
  50. data/lib/formtastic/inputs/base/stringish.rb +10 -2
  51. data/lib/formtastic/inputs/base/timeish.rb +34 -22
  52. data/lib/formtastic/inputs/base/validations.rb +41 -13
  53. data/lib/formtastic/inputs/base/wrapping.rb +29 -26
  54. data/lib/formtastic/inputs/base.rb +22 -15
  55. data/lib/formtastic/inputs/boolean_input.rb +26 -12
  56. data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
  57. data/lib/formtastic/inputs/color_input.rb +41 -0
  58. data/lib/formtastic/inputs/country_input.rb +24 -5
  59. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  60. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  61. data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
  62. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  63. data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
  64. data/lib/formtastic/inputs/file_input.rb +2 -2
  65. data/lib/formtastic/inputs/hidden_input.rb +2 -6
  66. data/lib/formtastic/inputs/radio_input.rb +28 -22
  67. data/lib/formtastic/inputs/select_input.rb +36 -39
  68. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  69. data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
  70. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  71. data/lib/formtastic/inputs.rb +32 -21
  72. data/lib/formtastic/localized_string.rb +1 -1
  73. data/lib/formtastic/localizer.rb +24 -24
  74. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  75. data/lib/formtastic/version.rb +1 -1
  76. data/lib/formtastic.rb +20 -10
  77. data/lib/generators/formtastic/form/form_generator.rb +10 -4
  78. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  79. data/lib/generators/formtastic/install/install_generator.rb +5 -19
  80. data/lib/generators/templates/_form.html.slim +2 -2
  81. data/lib/generators/templates/formtastic.rb +46 -25
  82. data/lib/generators/templates/input.rb +19 -0
  83. data/sample/basic_inputs.html +23 -3
  84. data/script/integration-template.rb +74 -0
  85. data/script/integration.sh +19 -0
  86. data/spec/action_class_finder_spec.rb +12 -0
  87. data/spec/actions/button_action_spec.rb +8 -8
  88. data/spec/actions/generic_action_spec.rb +92 -56
  89. data/spec/actions/input_action_spec.rb +7 -7
  90. data/spec/actions/link_action_spec.rb +10 -10
  91. data/spec/builder/custom_builder_spec.rb +36 -20
  92. data/spec/builder/error_proc_spec.rb +4 -4
  93. data/spec/builder/semantic_fields_for_spec.rb +28 -29
  94. data/spec/fast_spec_helper.rb +12 -0
  95. data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
  96. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  97. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  98. data/spec/helpers/action_helper_spec.rb +75 -103
  99. data/spec/helpers/actions_helper_spec.rb +17 -17
  100. data/spec/helpers/form_helper_spec.rb +84 -33
  101. data/spec/helpers/input_helper_spec.rb +333 -285
  102. data/spec/helpers/inputs_helper_spec.rb +167 -121
  103. data/spec/helpers/reflection_helper_spec.rb +3 -3
  104. data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
  105. data/spec/i18n_spec.rb +26 -26
  106. data/spec/input_class_finder_spec.rb +10 -0
  107. data/spec/inputs/base/collections_spec.rb +76 -0
  108. data/spec/inputs/base/validations_spec.rb +480 -0
  109. data/spec/inputs/boolean_input_spec.rb +100 -65
  110. data/spec/inputs/check_boxes_input_spec.rb +200 -101
  111. data/spec/inputs/color_input_spec.rb +85 -0
  112. data/spec/inputs/country_input_spec.rb +20 -20
  113. data/spec/inputs/custom_input_spec.rb +3 -4
  114. data/spec/inputs/datalist_input_spec.rb +61 -0
  115. data/spec/inputs/date_picker_input_spec.rb +449 -0
  116. data/spec/inputs/date_select_input_spec.rb +249 -0
  117. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  118. data/spec/inputs/datetime_select_input_spec.rb +209 -0
  119. data/spec/inputs/email_input_spec.rb +5 -5
  120. data/spec/inputs/file_input_spec.rb +6 -6
  121. data/spec/inputs/hidden_input_spec.rb +22 -35
  122. data/spec/inputs/include_blank_spec.rb +11 -11
  123. data/spec/inputs/label_spec.rb +62 -25
  124. data/spec/inputs/number_input_spec.rb +112 -112
  125. data/spec/inputs/password_input_spec.rb +5 -5
  126. data/spec/inputs/phone_input_spec.rb +5 -5
  127. data/spec/inputs/placeholder_spec.rb +6 -6
  128. data/spec/inputs/radio_input_spec.rb +99 -55
  129. data/spec/inputs/range_input_spec.rb +66 -66
  130. data/spec/inputs/readonly_spec.rb +50 -0
  131. data/spec/inputs/search_input_spec.rb +5 -5
  132. data/spec/inputs/select_input_spec.rb +170 -170
  133. data/spec/inputs/string_input_spec.rb +68 -16
  134. data/spec/inputs/text_input_spec.rb +16 -16
  135. data/spec/inputs/time_picker_input_spec.rb +455 -0
  136. data/spec/inputs/time_select_input_spec.rb +261 -0
  137. data/spec/inputs/time_zone_input_spec.rb +54 -28
  138. data/spec/inputs/url_input_spec.rb +5 -5
  139. data/spec/inputs/with_options_spec.rb +7 -7
  140. data/spec/localizer_spec.rb +39 -17
  141. data/spec/namespaced_class_finder_spec.rb +79 -0
  142. data/spec/schema.rb +21 -0
  143. data/spec/spec_helper.rb +254 -221
  144. data/spec/support/custom_macros.rb +128 -95
  145. data/spec/support/shared_examples.rb +12 -0
  146. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  147. data/spec/support/test_environment.rb +26 -10
  148. metadata +177 -238
  149. data/.travis.yml +0 -8
  150. data/Appraisals +0 -11
  151. data/CHANGELOG +0 -371
  152. data/gemfiles/rails-3.0.gemfile +0 -7
  153. data/gemfiles/rails-3.1.gemfile +0 -7
  154. data/gemfiles/rails-3.2.gemfile +0 -7
  155. data/lib/formtastic/helpers/buttons_helper.rb +0 -310
  156. data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
  157. data/lib/formtastic/util.rb +0 -25
  158. data/lib/tasks/verify_rcov.rb +0 -44
  159. data/spec/helpers/buttons_helper_spec.rb +0 -166
  160. data/spec/helpers/commit_button_helper_spec.rb +0 -530
  161. data/spec/inputs/date_input_spec.rb +0 -227
  162. data/spec/inputs/datetime_input_spec.rb +0 -185
  163. data/spec/inputs/time_input_spec.rb +0 -267
  164. data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -1,23 +1,31 @@
1
- h1. Formtastic
1
+ # Formtastic
2
+
3
+ [![Build Status](https://github.com/formtastic/formtastic/workflows/test/badge.svg)](https://github.com/formtastic/formtastic/actions)
4
+ [![Inline docs](https://inch-ci.org/github/justinfrench/formtastic.svg?branch=master)](https://inch-ci.org/github/justinfrench/formtastic)
5
+ [![Code Climate](https://codeclimate.com/github/formtastic/formtastic/badges/gpa.svg)](https://codeclimate.com/github/formtastic/formtastic)
6
+ [![Gem Version](https://badge.fury.io/rb/formtastic.svg)](https://badge.fury.io/rb/formtastic)
2
7
 
3
8
  Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.
4
9
 
5
- <a href='http://www.pledgie.com/campaigns/2178'><img alt='Click here to lend your support to: formtastic and make a donation at www.pledgie.com !' src='http://pledgie.com/campaigns/2178.png?skin_name=chrome' border='0' /></a>
10
+ ## Documentation & Support
6
11
 
12
+ * [Documentation is available on rdoc.info](https://rdoc.info/projects/formtastic/formtastic)
13
+ * [We track issues & bugs on GitHub](https://github.com/formtastic/formtastic/issues)
14
+ * [We have a wiki on GitHub](https://github.com/formtastic/formtastic/wiki)
15
+ * [StackOverflow can help](https://stackoverflow.com/questions/tagged/formtastic)
7
16
 
8
- h2. Compatibility
17
+ ## Compatibility
9
18
 
10
- * Formtastic 2.1.x is Rails 3.x compatible
11
- * Formtastic 2.0.x is Rails 3.0.x and 3.1.x compatible only
12
- * Formtastic 1.x is compatible with both Rails 2 and 3, and is being maintained for bug fixes in the the "1.2-stable branch":https://github.com/justinfrench/formtastic/tree/1.2-stable. View the README in that branch for installation instructions, etc.
19
+ * Formtastic 4 requires Rails 5.2 and Ruby 2.5 minimum
20
+ * Formtastic 3 requires Rails 3.2.13 minimum
21
+ * Formtastic 2 requires Rails 3
13
22
  * Formtastic, much like Rails, is very ActiveRecord-centric. Many are successfully using other ActiveModel-like ORMs and objects (DataMapper, MongoMapper, Mongoid, Authlogic, Devise...) but we're not guaranteeing full compatibility at this stage. Patches are welcome!
14
-
15
23
 
16
- h2. The Story
24
+ ## The Story
17
25
 
18
26
  One day, I finally had enough, so I opened up my text editor, and wrote a DSL for how I'd like to author forms:
19
27
 
20
- <pre>
28
+ ```erb
21
29
  <%= semantic_form_for @article do |f| %>
22
30
 
23
31
  <%= f.inputs :name => "Basic" do %>
@@ -47,16 +55,16 @@ One day, I finally had enough, so I opened up my text editor, and wrote a DSL fo
47
55
  <% end %>
48
56
 
49
57
  <% end %>
50
- </pre>
58
+ ```
51
59
 
52
- I also wrote the accompanying HTML output I expected, favoring something very similar to the fieldsets, lists and other semantic elements Aaron Gustafson presented in "Learning to Love Forms":http://www.slideshare.net/AaronGustafson/learning-to-love-forms-web-directions-south-07, hacking together enough Ruby to prove it could be done.
60
+ I also wrote the accompanying HTML output I expected, favoring something very similar to the fieldsets, lists and other semantic elements Aaron Gustafson presented in [Learning to Love Forms](https://www.slideshare.net/AaronGustafson/learning-to-love-forms-webvisions-07), hacking together enough Ruby to prove it could be done.
53
61
 
54
62
 
55
- h2. It's awesome because...
63
+ ## It's awesome because...
56
64
 
57
- * It can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
58
- * It can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
59
- * It's Rails 3 compatible (including nested forms).
65
+ * It can handle `belongs_to` associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
66
+ * It can handle `has_many` and `has_and_belongs_to_many` associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
67
+ * It's Rails 3/4 compatible (including nested forms).
60
68
  * It has internationalization (I18n)!
61
69
  * It's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
62
70
  * There's heaps of elements, id and class attributes for you to hook in your CSS and JS.
@@ -67,7 +75,7 @@ h2. It's awesome because...
67
75
  * It has growing HTML5 support (new inputs like email/phone/search, new attributes like required/min/max/step/placeholder)
68
76
 
69
77
 
70
- h2. Opinions
78
+ ## Opinions
71
79
 
72
80
  * It should be easier to do things the right way than the wrong way.
73
81
  * Sometimes _more mark-up_ is better.
@@ -75,95 +83,82 @@ h2. Opinions
75
83
  * Make the common things we do easy, yet ensure uncommon things are still possible.
76
84
 
77
85
 
78
- h2. Documentation
79
-
80
- RDoc documentation _should_ be automatically generated after each commit and made available on the "rdoc.info website":http://rdoc.info/projects/justinfrench/formtastic.
81
-
82
-
83
- h2. Installation
86
+ ## Installation
84
87
 
85
88
  Simply add Formtastic to your Gemfile and bundle it up:
86
89
 
87
- <pre>
88
- gem 'formtastic'
89
- </pre>
90
+ ```ruby
91
+ gem 'formtastic', '~> 4.0'
92
+ ```
90
93
 
91
94
  Run the installation generator:
92
95
 
93
- <pre>
94
- $ rails generate formtastic:install
95
- </pre>
96
+ ```shell
97
+ $ rails generate formtastic:install
98
+ ```
96
99
 
97
100
 
98
- h2. Stylesheets
101
+ ## Stylesheets
99
102
 
100
103
  A proof-of-concept set of stylesheets are provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet.
101
104
 
102
- h3. Stylesheet usage in Rails < 3.1:
103
-
104
- <pre>
105
- $ rails generate formtastic:install
106
- </pre>
107
-
108
- <pre>
109
- # app/views/layouts/application.html.erb
110
- <%= stylesheet_link_tag 'formtastic', 'my_formtastic_changes' %>
111
- <!--[if IE 6]><%= stylesheet_link_tag 'formtastic_ie6' %><![endif]-->
112
- <!--[if IE 7]><%= stylesheet_link_tag 'formtastic_ie7' %><![endif]-->
113
- </pre>
114
-
115
- h3. Stylesheet usage in Rails >= 3.1:
116
-
117
- Rails 3.1 introduces an asset pipeline that allows plugins like Formtastic to serve their own Stylesheets, Javascripts, etc without having to run generators that copy them accross to the host application. Formtastic makes three stylesheets available as an Engine, you just need to require them in your global stylesheets.
105
+ Rails 3.1 introduces an asset pipeline that allows plugins like Formtastic to serve their own Stylesheets, Javascripts, etc without having to run generators that copy them across to the host application. Formtastic makes three stylesheets available as an Engine, you just need to require them in your global stylesheets.
118
106
 
119
- <pre>
107
+ ```css
120
108
  # app/assets/stylesheets/application.css
121
109
  *= require formtastic
122
110
  *= require my_formtastic_changes
123
-
111
+ ```
112
+
113
+ Conditional stylesheets need to be compiled separately to prevent them being bundled and included with other application styles. Remove `require_tree .` from application.css and specify required stylesheets individually.
114
+
115
+ ```css
124
116
  # app/assets/stylesheets/ie6.css
125
117
  *= require formtastic_ie6
126
-
118
+
127
119
  # app/assets/stylesheets/ie7.css
128
120
  *= require formtastic_ie7
129
- </pre>
121
+ ```
130
122
 
131
- <pre>
123
+ ```erb
132
124
  # app/views/layouts/application.html.erb
133
125
  <%= stylesheet_link_tag 'application' %>
134
126
  <!--[if IE 6]><%= stylesheet_link_tag 'ie6' %><![endif]-->
135
127
  <!--[if IE 7]><%= stylesheet_link_tag 'ie7' %><![endif]-->
136
- </pre>
137
-
128
+ ```
138
129
 
130
+ ```ruby
131
+ # config/environments/production.rb
132
+ config.assets.precompile += %w( ie6.css ie7.css )
133
+ ```
139
134
 
140
- h2. Usage
135
+ ## Usage
141
136
 
142
137
  Forms are really boring to code... you want to get onto the good stuff as fast as possible.
143
138
 
144
- This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by default action buttons (an input submit button):
139
+ This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord `belongs_to`-association), followed by default action buttons (an input submit button):
145
140
 
146
- <pre>
141
+ ```erb
147
142
  <%= semantic_form_for @user do |f| %>
148
143
  <%= f.inputs %>
149
144
  <%= f.actions %>
150
145
  <% end %>
151
- </pre>
146
+ ```
152
147
 
153
148
  This is a great way to get something up fast, but like scaffolding, it's *not recommended for production*. Don't be so lazy!
154
149
 
155
- To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to @inputs@ and list of action names to @actions@:
150
+ To specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't infer. You can pass in a list of field names to `inputs` and list of action names to `actions`:
156
151
 
157
- <pre>
152
+ ```erb
158
153
  <%= semantic_form_for @user do |f| %>
159
154
  <%= f.inputs :title, :body, :section, :categories, :created_at %>
160
155
  <%= f.actions :submit, :cancel %>
161
156
  <% end %>
162
- </pre>
157
+ ```
163
158
 
164
- You probably want control over the input type Formtastic uses for each field. You can expand the @inputs@ and @actions@ to block helper format and use the @:as@ option to specify an exact input type:
159
+ You probably want control over the input type Formtastic uses for each field. You can expand the `inputs` and `actions` to block helper format and use the `:as` option to specify an exact input type:
165
160
 
166
- <pre>
161
+ ```erb
167
162
  <%= semantic_form_for @post do |f| %>
168
163
  <%= f.inputs do %>
169
164
  <%= f.input :title %>
@@ -177,11 +172,11 @@ You probably want control over the input type Formtastic uses for each field. Yo
177
172
  <%= f.action :cancel, :as => :link %>
178
173
  <% end %>
179
174
  <% end %>
180
- </pre>
175
+ ```
181
176
 
182
177
  If you want to customize the label text, or render some hint text below the field, specify which fields are required/optional, or break the form into two fieldsets, the DSL is pretty comprehensive:
183
178
 
184
- <pre>
179
+ ```erb
185
180
  <%= semantic_form_for @post do |f| %>
186
181
  <%= f.inputs "Basic", :id => "basic" do %>
187
182
  <%= f.input :title %>
@@ -190,7 +185,7 @@ If you want to customize the label text, or render some hint text below the fiel
190
185
  <%= f.inputs :name => "Advanced Options", :id => "advanced" do %>
191
186
  <%= f.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
192
187
  <%= f.input :section, :as => :radio %>
193
- <%= f.input :user, :label => "Author", :member_label => :full_name %>
188
+ <%= f.input :user, :label => "Author" %>
194
189
  <%= f.input :categories, :required => false %>
195
190
  <%= f.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
196
191
  <% end %>
@@ -198,17 +193,17 @@ If you want to customize the label text, or render some hint text below the fiel
198
193
  <%= f.action :submit %>
199
194
  <% end %>
200
195
  <% end %>
201
- </pre>
196
+ ```
202
197
 
203
198
  You can create forms for nested resources:
204
199
 
205
- <pre>
200
+ ```erb
206
201
  <%= semantic_form_for [@author, @post] do |f| %>
207
- </pre>
202
+ ```
208
203
 
209
- Nested forms are also supported (don't forget your models need to be setup correctly with @accepts_nested_attributes_for@). You can do it in the Rails way:
204
+ Nested forms are also supported (don't forget your models need to be setup correctly with `accepts_nested_attributes_for`). You can do it in the Rails way:
210
205
 
211
- <pre>
206
+ ```erb
212
207
  <%= semantic_form_for @post do |f| %>
213
208
  <%= f.inputs :title, :body, :created_at %>
214
209
  <%= f.semantic_fields_for :author do |author| %>
@@ -216,46 +211,41 @@ Nested forms are also supported (don't forget your models need to be setup corre
216
211
  <% end %>
217
212
  <%= f.actions %>
218
213
  <% end %>
219
- </pre>
214
+ ```
220
215
 
221
- Or the Formtastic way with the @:for@ option:
216
+ Or the Formtastic way with the `:for` option:
222
217
 
223
- <pre>
218
+ ```erb
224
219
  <%= semantic_form_for @post do |f| %>
225
220
  <%= f.inputs :title, :body, :created_at %>
226
221
  <%= f.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
227
222
  <%= f.actions %>
228
223
  <% end %>
229
- </pre>
224
+ ```
230
225
 
231
- When working in has many association, you can even supply @"%i"@ in your fieldset name; they will be properly interpolated with the child index. For example:
226
+ When working in has many association, you can even supply `"%i"` in your fieldset name; they will be properly interpolated with the child index. For example:
232
227
 
233
- <pre>
228
+ ```erb
234
229
  <%= semantic_form_for @post do |f| %>
235
230
  <%= f.inputs %>
236
231
  <%= f.inputs :name => 'Category #%i', :for => :categories %>
237
232
  <%= f.actions %>
238
233
  <% end %>
239
- </pre>
234
+ ```
240
235
 
241
236
  Alternatively, the current index can be accessed via the `inputs` block's arguments for use anywhere:
242
237
 
243
- <pre>
238
+ ```erb
244
239
  <%= semantic_form_for @post do |f| %>
245
240
  <%= f.inputs :for => :categories do |category, i| %>
246
- <% if i <= 2 %>
247
- <%= f.inputs :name => "Category ##{i}" %>
248
- <% else %>
249
- <%= f.inputs :name => "Category ##{i} (optional)" %>
250
- <% end %>
251
- <% end %>
241
+ ...
252
242
  <%= f.actions %>
253
243
  <% end %>
254
- </pre>
244
+ ```
255
245
 
256
246
  If you have more than one form on the same page, it may lead to HTML invalidation because of the way HTML element id attributes are assigned. You can provide a namespace for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generate HTML id. For example:
257
247
 
258
- <pre>
248
+ ```erb
259
249
  <%= semantic_form_for(@post, :namespace => 'cat_form') do |f| %>
260
250
  <%= f.inputs do %>
261
251
  <%= f.input :title %> # id="cat_form_post_title"
@@ -264,11 +254,11 @@ If you have more than one form on the same page, it may lead to HTML invalidatio
264
254
  <% end %>
265
255
  <%= f.actions %>
266
256
  <% end %>
267
- </pre>
257
+ ```
268
258
 
269
- Customize HTML attributes for any input using the @:input_html@ option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrowtextarea textareas:
259
+ Customize HTML attributes for any input using the `:input_html` option. Typically this is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like [autogrow](https://plugins.jquery.com/project/autogrowtextarea) textareas:
270
260
 
271
- <pre>
261
+ ```erb
272
262
  <%= semantic_form_for @post do |f| %>
273
263
  <%= f.inputs do %>
274
264
  <%= f.input :title, :input_html => { :size => 10 } %>
@@ -278,22 +268,22 @@ Customize HTML attributes for any input using the @:input_html@ option. Typicall
278
268
  <% end %>
279
269
  <%= f.actions %>
280
270
  <% end %>
281
- </pre>
271
+ ```
282
272
 
283
- The same can be done for actions with the @:button_html@ option:
273
+ The same can be done for actions with the `:button_html` option:
284
274
 
285
- <pre>
275
+ ```erb
286
276
  <%= semantic_form_for @post do |f| %>
287
277
  ...
288
278
  <%= f.actions do %>
289
279
  <%= f.action :submit, :button_html => { :class => "primary", :disable_with => 'Wait...' } %>
290
280
  <% end %>
291
281
  <% end %>
292
- </pre>
282
+ ```
293
283
 
294
- Customize the HTML attributes for the @<li>@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash: (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@).
284
+ Customize the HTML attributes for the `<li>` wrapper around every input with the `:wrapper_html` option hash. There's one special key in the hash: (`:class`), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like `"required string error"`).
295
285
 
296
- <pre>
286
+ ```erb
297
287
  <%= semantic_form_for @post do |f| %>
298
288
  <%= f.inputs do %>
299
289
  <%= f.input :title, :wrapper_html => { :class => "important" } %>
@@ -302,84 +292,80 @@ Customize the HTML attributes for the @<li>@ wrapper around every input with the
302
292
  <% end %>
303
293
  ...
304
294
  <% end %>
305
- </pre>
306
-
307
- Customize the default class used for hints on each attribute or globally in the @config/initializers/formtastic.rb@ file. Similarly, you can customize the error classes on an attribute level or globally.
308
-
309
- <pre>
310
- <%= semantic_form_for @post do |f| %>
311
- <%= f.inputs do %>
312
- <%= f.input :title, :hint_class => 'custom-html-class', :error_class => 'custom-error-class' %>
313
- <% end %>
314
- <% end %>
315
- </pre>
295
+ ```
316
296
 
317
- Many inputs provide a collection of options to choose from (like @:select@, @:radio@, @:check_boxes@, @:boolean@). In many cases, Formtastic can find choices through the model associations, but if you want to use your own set of choices, the @:collection@ option is what you want. You can pass in an Array of objects, an array of Strings, a Hash... Throw almost anything at it! Examples:
297
+ Many inputs provide a collection of options to choose from (like `:select`, `:radio`, `:check_boxes`, `:boolean`). In many cases, Formtastic can find choices through the model associations, but if you want to use your own set of choices, the `:collection` option is what you want. You can pass in an Array of objects, an array of Strings, a Hash... Throw almost anything at it! Examples:
318
298
 
319
- <pre>
320
- f.input :authors, :as => :check_boxes, :collection => User.find(:all, :order => "last_name ASC")
299
+ ```ruby
300
+ f.input :authors, :as => :check_boxes, :collection => User.order("last_name ASC").all
321
301
  f.input :authors, :as => :check_boxes, :collection => current_user.company.users.active
322
302
  f.input :authors, :as => :check_boxes, :collection => [@justin, @kate]
323
303
  f.input :authors, :as => :check_boxes, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
324
- f.input :author, :as => :select, :collection => Author.find(:all)
304
+ f.input :author, :as => :select, :collection => Author.all
305
+ f.input :author, :as => :select, :collection => Author.pluck(:first_name, :id)
306
+ f.input :author, :as => :select, :collection => Author.pluck(Arel.sql("CONCAT(`first_name`, ' ', `last_name`)"), :id)
307
+ f.input :author, :as => :select, :collection => Author.your_custom_scope_or_class_method
325
308
  f.input :author, :as => :select, :collection => { @justin.name => @justin.id, @kate.name => @kate.id }
326
309
  f.input :author, :as => :select, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
327
- f.input :author, :as => :radio, :collection => User.find(:all)
310
+ f.input :author, :as => :radio, :collection => User.all
328
311
  f.input :author, :as => :radio, :collection => [@justin, @kate]
329
312
  f.input :author, :as => :radio, :collection => { @justin.name => @justin.id, @kate.name => @kate.id }
330
313
  f.input :author, :as => :radio, :collection => ["Justin", "Kate", "Amelia", "Gus", "Meg"]
331
314
  f.input :admin, :as => :radio, :collection => ["Yes!", "No"]
332
- </pre>
315
+ f.input :book_id, :as => :select, :collection => Hash[Book.all.map{|b| [b.name,b.id]}]
316
+ f.input :fav_book,:as => :datalist , :collection => Book.pluck(:name)
317
+ ```
333
318
 
334
319
 
335
- h2. The Available Inputs
320
+ ## The Available Inputs
336
321
 
337
322
  The Formtastic input types:
338
323
 
339
- * @:select@ - a select menu. Default for ActiveRecord associations: @belongs_to@, @has_many@, and @has_and_belongs_to_many@.
340
- * @:check_boxes@ - a set of check_box inputs. Alternative to @:select@ for ActiveRecord-associations: @has_many@, and @has_and_belongs_to_many@.
341
- * @:radio@ - a set of radio inputs. Alternative to @:select@ for ActiveRecord-associations: @belongs_to@.
342
- * @:time_zone@ - a select input. Default for column types: @:string@ with name matching @"time_zone"@.
343
- * @:password@ - a password input. Default for column types: @:string@ with name matching @"password"@.
344
- * @:text@ - a textarea. Default for column types: @:text@.
345
- * @:date@ - a date select. Default for column types: @:date@.
346
- * @:datetime@ - a date and time select. Default for column types: @:datetime@ and @:timestamp@.
347
- * @:time@ - a time select. Default for column types: @:time@.
348
- * @:boolean@ - a checkbox. Default for column types: @:boolean@.
349
- * @:string@ - a text field. Default for column types: @:string@.
350
- * @:number@ - a text field (just like string). Default for column types: @:integer@, @:float@, and @:decimal@.
351
- * @:file@ - a file field. Default for file-attachment attributes matching: "paperclip":http://github.com/thoughtbot/paperclip or "attachment_fu":http://github.com/technoweenie/attachment_fu.
352
- * @:country@ - a select menu of country names. Default for column types: :string with name @"country"@ - requires a *country_select* plugin to be installed.
353
- * @:email@ - a text field (just like string). Default for columns with name matching @"email"@. New in HTML5. Works on some mobile browsers already.
354
- * @:url@ - a text field (just like string). Default for columns with name matching @"url"@. New in HTML5. Works on some mobile browsers already.
355
- * @:phone@ - a text field (just like string). Default for columns with name matching @"phone"@ or @"fax"@. New in HTML5.
356
- * @:search@ - a text field (just like string). Default for columns with name matching @"search"@. New in HTML5. Works on Safari.
357
- * @:hidden@ - a hidden field. Creates a hidden field (added for compatibility).
358
- * @:range@ - a slider field.
324
+ * `:select` - a select menu. Default for ActiveRecord associations: `belongs_to`, `has_many`, and `has_and_belongs_to_many`.
325
+ * `:check_boxes` - a set of check_box inputs. Alternative to `:select` for ActiveRecord-associations: `has_many`, and has_and_belongs_to_many`.
326
+ * `:radio` - a set of radio inputs. Alternative to `:select` for ActiveRecord-associations: `belongs_to`.
327
+ * `:time_zone` - a select input. Default for column types: `:string` with name matching `"time_zone"`.
328
+ * `:password` - a password input. Default for column types: `:string` with name matching `"password"`.
329
+ * `:text` - a textarea. Default for column types: `:text`.
330
+ * `:date_select` - a date select. Default for column types: `:date`.
331
+ * `:datetime_select` - a date and time select. Default for column types: `:datetime` and `:timestamp`.
332
+ * `:time_select` - a time select. Default for column types: `:time`.
333
+ * `:boolean` - a checkbox. Default for column types: `:boolean`.
334
+ * `:string` - a text field. Default for column types: `:string`.
335
+ * `:number` - a text field (just like string). Default for column types: `:integer`, `:float`, and `:decimal`.
336
+ * `:file` - a file field. Default for file-attachment attributes matching: [paperclip](https://github.com/thoughtbot/paperclip) or [attachment_fu](https://github.com/technoweenie/attachment_fu).
337
+ * `:country` - a select menu of country names. Default for column types: `:string` with name `"country"` - requires a *country_select* plugin to be installed.
338
+ * `:email` - a text field (just like string). Default for columns with name matching `"email"`. New in HTML5. Works on some mobile browsers already.
339
+ * `:url` - a text field (just like string). Default for columns with name matching `"url"`. New in HTML5. Works on some mobile browsers already.
340
+ * `:phone` - a text field (just like string). Default for columns with name matching `"phone"` or `"fax"`. New in HTML5.
341
+ * `:search` - a text field (just like string). Default for columns with name matching `"search"`. New in HTML5. Works on Safari.
342
+ * `:hidden` - a hidden field. Creates a hidden field (added for compatibility).
343
+ * `:range` - a slider field.
344
+ * `:datalist` - a text field with a accompanying [datalist tag](https://developer.mozilla.org/en/docs/Web/HTML/Element/datalist) which provides options for autocompletion
359
345
 
360
346
  The comments in the code are pretty good for each of these (what it does, what the output is, what the options are, etc.) so go check it out.
361
347
 
362
348
 
363
- h2. Delegation for label lookups
349
+ ## Delegation for label lookups
364
350
 
365
351
  Formtastic decides which label to use in the following order:
366
352
 
367
- <pre>
353
+ ```
368
354
  1. :label # :label => "Choose Title"
369
355
  2. Formtastic i18n # if either :label => true || i18n_lookups_by_default = true (see Internationalization)
370
356
  3. Activerecord i18n # if localization file found for the given attribute
371
- 4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
372
- </pre>
357
+ 4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
358
+ ```
373
359
 
374
- h2. Internationalization (I18n)
360
+ ## Internationalization (I18n)
375
361
 
376
- h3. Basic Localization
362
+ ### Basic Localization
377
363
 
378
- Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
364
+ Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling `@object.human_name` and `@object.human_attribute_name(attr)` respectively. There are a few words specific to Formtastic that can be translated. See `lib/locale/en.yml` for more information.
379
365
 
380
366
  Basic localization (labels only, with ActiveRecord):
381
367
 
382
- <pre>
368
+ ```erb
383
369
  <%= semantic_form_for @post do |f| %>
384
370
  <%= f.inputs do %>
385
371
  <%= f.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
@@ -387,23 +373,23 @@ Basic localization (labels only, with ActiveRecord):
387
373
  <%= f.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
388
374
  <% end %>
389
375
  <% end %>
390
- </pre>
376
+ ```
391
377
 
392
378
  *Note:* This is perfectly fine if you just want your labels/attributes and/or models to be translated using *ActiveRecord I18n attribute translations*, and you don't use input hints and legends. But what if you do? And what if you don't want same labels in all forms?
393
379
 
394
- h3. Enhanced Localization (Formtastic I18n API)
380
+ ### Enhanced Localization (Formtastic I18n API)
395
381
 
396
382
  Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the I18n API for more advanced usage. Your forms can now be DRYer and more flexible than ever, and still fully localized. This is how:
397
383
 
398
- *1. Enable I18n lookups by default (@config/initializers/formtastic.rb@):*
384
+ *1. Enable I18n lookups by default (`config/initializers/formtastic.rb`):*
399
385
 
400
- <pre>
386
+ ```ruby
401
387
  Formtastic::FormBuilder.i18n_lookups_by_default = true
402
- </pre>
388
+ ```
403
389
 
404
- *2. Add some cool label-translations/variants (@config/locale/en.yml@):*
390
+ *2. Add some label-translations/variants (`config/locales/en.yml`):*
405
391
 
406
- <pre>
392
+ ```yml
407
393
  en:
408
394
  formtastic:
409
395
  titles:
@@ -430,11 +416,11 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
430
416
  reset: "Reset form"
431
417
  cancel: "Cancel and go back"
432
418
  dummie: "Launch!"
433
- </pre>
419
+ ```
434
420
 
435
421
  *3. ...and now you'll get:*
436
422
 
437
- <pre>
423
+ ```erb
438
424
  <%= semantic_form_for Post.new do |f| %>
439
425
  <%= f.inputs do %>
440
426
  <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
@@ -445,24 +431,24 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
445
431
  <%= f.action :submit %> # => "Create my %{model}"
446
432
  <% end %>
447
433
  <% end %>
448
- </pre>
434
+ ```
449
435
 
450
436
  *4. Localized titles (a.k.a. legends):*
451
437
 
452
438
  _Note: Slightly different because Formtastic can't guess how you group fields in a form. Legend text can be set with first (as in the sample below) specified value, or :name/:title options - depending on what flavor is preferred._
453
439
 
454
- <pre>
440
+ ```erb
455
441
  <%= semantic_form_for @post do |f| %>
456
442
  <%= f.inputs :post_details do %> # => :title => "Post details"
457
443
  # ...
458
444
  <% end %>
459
445
  # ...
460
446
  <% end %>
461
- </pre>
447
+ ```
462
448
 
463
449
  *5. Override I18n settings:*
464
450
 
465
- <pre>
451
+ ```erb
466
452
  <%= semantic_form_for @post do |f| %>
467
453
  <%= f.inputs do %>
468
454
  <%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
@@ -473,17 +459,17 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
473
459
  <%= f.action :submit, :label => :dummie %> # => "Launch!"
474
460
  <% end %>
475
461
  <% end %>
476
- </pre>
462
+ ```
477
463
 
478
464
  If I18n-lookups is disabled, i.e.:
479
465
 
480
- <pre>
466
+ ```ruby
481
467
  Formtastic::FormBuilder.i18n_lookups_by_default = false
482
- </pre>
468
+ ```
483
469
 
484
470
  ...then you can enable I18n within the forms instead:
485
471
 
486
- <pre>
472
+ ```erb
487
473
  <%= semantic_form_for @post do |f| %>
488
474
  <%= f.inputs do %>
489
475
  <%= f.input :title, :label => true %> # => :label => "Choose a title..."
@@ -494,25 +480,25 @@ If I18n-lookups is disabled, i.e.:
494
480
  <%= f.action :submit, :label => true %> # => "Update %{model}" (if we are in edit that is...)
495
481
  <% end %>
496
482
  <% end %>
497
- </pre>
483
+ ```
498
484
 
499
485
  *6. Advanced I18n lookups*
500
486
 
501
487
  For more flexible forms; Formtastic finds translations using a bottom-up approach taking the following variables in account:
502
488
 
503
- * @MODEL@, e.g. "post"
504
- * @ACTION@, e.g. "edit"
505
- * @KEY/ATTRIBUTE@, e.g. "title", :my_custom_key, ...
489
+ * `MODEL`, e.g. "post"
490
+ * `ACTION`, e.g. "edit"
491
+ * `KEY/ATTRIBUTE`, e.g. "title", :my_custom_key, ...
506
492
 
507
493
  ...in the following order:
508
494
 
509
- 1. @formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE@ - by model and action
510
- 2. @formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE@ - by model
511
- 3. @formtastic.{titles,labels,hints,actions}.ATTRIBUTE@ - global default
495
+ 1. `formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE` - by model and action
496
+ 2. `formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE` - by model
497
+ 3. `formtastic.{titles,labels,hints,actions}.ATTRIBUTE` - global default
512
498
 
513
499
  ...which means that you can define translations like this:
514
500
 
515
- <pre>
501
+ ```yml
516
502
  en:
517
503
  formtastic:
518
504
  labels:
@@ -526,117 +512,116 @@ For more flexible forms; Formtastic finds translations using a bottom-up approac
526
512
  edit:
527
513
  title: "Edit title"
528
514
  body: "Edit body"
529
- </pre>
515
+ ```
530
516
 
531
- Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit value), @Symbol@ (i18n-lookup-key relative to the current "type", e.g. actions:), @true@ (force I18n lookup), @false@ (force no I18n lookup). Titles (legends) can only take: @String@ and @Symbol@ - true/false have no meaning.
517
+ Values for `labels`/`hints`/`actions` are can take values: `String` (explicit value), `Symbol` (i18n-lookup-key relative to the current "type", e.g. actions:), `true` (force I18n lookup), `false` (force no I18n lookup). Titles (legends) can only take: `String` and `Symbol` - true/false have no meaning.
532
518
 
519
+ *7. Basic Translations*
520
+ If you want some basic translations, take a look on the [formtastic_i18n gem](https://github.com/timoschilling/formtastic_i18n).
533
521
 
534
- h2. Semantic errors
522
+ ## Semantic errors
535
523
 
536
- You can show errors on base (by default) and any other attribute just passing it name to semantic_errors method:
524
+ You can show errors on base (by default) and any other attribute just by passing its name to the semantic_errors method:
537
525
 
538
- <pre>
526
+ ```erb
539
527
  <%= semantic_form_for @post do |f| %>
540
528
  <%= f.semantic_errors :state %>
541
529
  <% end %>
542
- </pre>
530
+ ```
543
531
 
544
532
 
545
- h2. Modified & Custom Inputs
533
+ ## Modified & Custom Inputs
546
534
 
547
535
  You can modify existing inputs, subclass them, or create your own from scratch. Here's the basic process:
548
536
 
549
- * Create a file in @app/inputs@ with a filename ending in @_input.rb@. For example, @app/inputs/hat_size_input.rb@. Formtastic will automatically look in @app/inputs@ and find the file.
550
- * In that file, declare a classname ending in @Input@. For example, @class HatSizeInput@. It must have a @to_html@ method for rendering.
551
- * To use that input, leave off the word "input" in your @as@ statement. For example, @f.input(:size, :as => :hat_size)@
537
+ * Run the input generator and provide your custom input name. For example, `rails generate formtastic:input hat_size`. This creates the file `app/inputs/hat_size_input.rb`. You can also provide namespace to input name like `rails generate formtastic:input foo/custom` or `rails generate formtastic:input Foo::Custom`, this will create the file `app/inputs/foo/custom_input.rb` in both cases.
538
+ * To use that input, leave off the word "input" in your `as` statement. For example, `f.input(:size, :as => :hat_size)`
552
539
 
553
540
  Specific examples follow.
554
541
 
555
- h3. Changing Existing Input Behavior
542
+ ### Changing Existing Input Behavior
556
543
 
557
- To modify the behavior of @StringInput@, subclass it in a new file, @app/inputs/string_input.rb@:
544
+ To modify the behavior of `StringInput`, subclass it in a new file, `app/inputs/string_input.rb`:
558
545
 
559
- <pre>
546
+ ```ruby
560
547
  class StringInput < Formtastic::Inputs::StringInput
561
548
  def to_html
562
549
  puts "this is my modified version of StringInput"
563
550
  super
564
551
  end
565
552
  end
566
- </pre>
553
+ ```
554
+
555
+ Another way to modify behavior is by using the input generator:
556
+ ```shell
557
+ $ rails generate formtastic:input string --extend
558
+ ```
559
+
560
+ This generates the file `app/inputs/string_input.rb` with its respective content class.
567
561
 
568
- You can use your modified version with @:as => :string@.
562
+ You can use your modified version with `:as => :string`.
569
563
 
570
- h3. Creating New Inputs Based on Existing Ones
564
+ ### Creating New Inputs Based on Existing Ones
571
565
 
572
- To create your own new types of inputs based on existing inputs, the process is similar. For example, to create @FlexibleTextInput@ based on @StringInput@, put the following in @app/inputs/flexible_text_input.rb@:
566
+ To create your own new types of inputs based on existing inputs, the process is similar. For example, to create `FlexibleTextInput` based on `StringInput`, put the following in `app/inputs/flexible_text_input.rb`:
573
567
 
574
- <pre>
568
+ ```ruby
575
569
  class FlexibleTextInput < Formtastic::Inputs::StringInput
576
570
  def input_html_options
577
571
  super.merge(:class => "flexible-text-area")
578
572
  end
579
573
  end
580
- </pre>
574
+ ```
581
575
 
582
- You can use your new input with @:as => :flexible_text@.
576
+ You can also extend existing input behavior by using the input generator:
583
577
 
584
- h3. Creating New Inputs From Scratch
578
+ ```shell
579
+ $ rails generate formtastic:input FlexibleText --extend string
580
+ ```
585
581
 
586
- To create a custom @DatePickerInput@ from scratch, put the following in @app/inputs/date_picker_input.rb@:
582
+ This generates the file `app/inputs/flexible_text_input.rb` with its respective content class.
587
583
 
588
- <pre>
584
+ You can use your new input with `:as => :flexible_text`.
585
+
586
+ ### Creating New Inputs From Scratch
587
+
588
+ To create a custom `DatePickerInput` from scratch, put the following in `app/inputs/date_picker_input.rb`:
589
+
590
+ ```ruby
589
591
  class DatePickerInput
590
592
  include Formtastic::Inputs::Base
591
593
  def to_html
592
594
  # ...
593
595
  end
594
596
  end
595
- </pre>
596
-
597
- You can use your new input with @:as => :date_picker@.
597
+ ```
598
598
 
599
- h3. Don't subclass Formtastic::FormBuilder anymore
599
+ You can use your new input with `:as => :date_picker`.
600
600
 
601
- It was previously recommended in Formtastic 1.x to subclass Formtastic::FormBuilder to add your own inputs. This is no longer recommended in Formtastic 2, and will not work as expected.
602
601
 
602
+ ## Dependencies
603
603
 
604
- h2. Security
604
+ There are none other than Rails itself, but...
605
605
 
606
- By default, Formtastic escapes HTML entities in both labels and hints unless a string is marked as html_safe. If you are using an older rails version which doesn't know html_safe, or you want to globally turn this feature off, you can set the following in your initializer:
606
+ * If you want to use the `:country` input, you'll need to install the [country-select plugin](https://github.com/stefanpenner/country_select) (or any other country_select plugin with the same API). Both 1.x and 2.x are supported, but they behave differently when storing data, so please see their [upgrade notes](https://github.com/stefanpenner/country_select/blob/master/UPGRADING.md) if switching from 1.x.
607
+ * There are a bunch of development dependencies if you plan to contribute to Formtastic
607
608
 
608
- Formtastic::FormBuilder.escape_html_entities_in_hints_and_labels = false
609
609
 
610
-
611
- h2. Dependencies
612
-
613
- There are none, but...
614
-
615
- * If you want to use the @:country@ input, you'll need to install the "country-select plugin":https://github.com/chrislerum/country_select (or any other country_select plugin with the same API).
616
- * "rspec":http://github.com/dchelimsky/rspec/, "rspec_hpricot_matchers":http://rubyforge.org/projects/rspec-hpricot/ and "rcov":http://github.com/relevance/rcov gems (plus any of their own dependencies) are required for the test suite.
617
-
618
-
619
- h2. How to contribute
610
+ ## How to contribute
620
611
 
621
612
  * Fork the project on Github
613
+ * Install development dependencies (`bundle install` and `bin/appraisal install`)
622
614
  * Create a topic branch for your changes
615
+ * Ensure that you provide *documentation* and *test coverage* for your changes (patches won't be accepted without)
623
616
  * Ensure that all tests pass (`bundle exec rake`)
624
- * Ensure that the changes in your branch are as atomic as possible
625
- * Create a pull request on Github
626
-
627
- For significant changes, you may wish to discuss your idea on the Formtastic Google group before coding to ensure that your change is likely to be accepted. Formtastic relies heavily on i18n, so if you're unsure of the impact this has on your changes, please discuss them with the group.
628
-
629
-
630
- h2. Google Group, Twitter, etc
617
+ * Create a pull request on Github (these are also a great place to start a conversation around a patch as early as possible)
631
618
 
632
- Please join the "Formtastic Google Group":http://groups.google.com.au/group/formtastic, especially if you'd like to talk about a new feature, or report a bug.
633
619
 
634
- You can also follow "@justinfrench":http://twitter.com/formtastic or "@formtastic":http://twitter.com/formtastic on Twitter for announcements, tutorials and links.
620
+ ## Project Info
635
621
 
636
- h2. Project Info
622
+ Formtastic was created by [Justin French](https://www.justinfrench.com) with contributions from around 180 awesome developers. Run `git shortlog -n -s` to see the awesome.
637
623
 
638
- Formtastic was created by "Justin French":http://www.justinfrench.com with contributions from around 150 awesome developers. Run @git shortlog -n -s@ to see the awesome.
624
+ The project is hosted on Github: [https://github.com/formtastic/formtastic](https://github.com/formtastic/formtastic), where your contributions, forkings, comments, issues and feedback are greatly welcomed.
639
625
 
640
- The project is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments, issues and feedback are greatly welcomed.
626
+ Copyright (c) 2007-2021, released under the MIT license.
641
627
 
642
- Copyright (c) 2007-2012 Justin French, released under the MIT license.