formtastic 2.1.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +1 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +4 -2
- data/CHANGELOG.md +52 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +105 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +204 -219
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +27 -29
- data/app/assets/stylesheets/formtastic.css +3 -2
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +11 -14
- data/gemfiles/rails_5.2/Gemfile +5 -0
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_6.1/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/action_class_finder.rb +18 -0
- data/lib/formtastic/actions/button_action.rb +55 -60
- data/lib/formtastic/actions/input_action.rb +59 -57
- data/lib/formtastic/actions/link_action.rb +68 -67
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +5 -0
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +35 -16
- data/lib/formtastic/helpers/action_helper.rb +34 -28
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
- data/lib/formtastic/helpers/form_helper.rb +19 -16
- data/lib/formtastic/helpers/input_helper.rb +69 -97
- data/lib/formtastic/helpers/inputs_helper.rb +35 -25
- data/lib/formtastic/helpers/reflection.rb +4 -4
- data/lib/formtastic/helpers.rb +1 -2
- data/lib/formtastic/html_attributes.rb +12 -1
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/input_class_finder.rb +18 -0
- data/lib/formtastic/inputs/base/choices.rb +2 -2
- data/lib/formtastic/inputs/base/collections.rb +46 -14
- data/lib/formtastic/inputs/base/database.rb +7 -2
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
- data/lib/formtastic/inputs/base/errors.rb +7 -7
- data/lib/formtastic/inputs/base/hints.rb +2 -2
- data/lib/formtastic/inputs/base/html.rb +10 -9
- data/lib/formtastic/inputs/base/labelling.rb +5 -8
- data/lib/formtastic/inputs/base/naming.rb +4 -4
- data/lib/formtastic/inputs/base/numeric.rb +1 -1
- data/lib/formtastic/inputs/base/options.rb +3 -4
- data/lib/formtastic/inputs/base/stringish.rb +10 -2
- data/lib/formtastic/inputs/base/timeish.rb +34 -22
- data/lib/formtastic/inputs/base/validations.rb +41 -13
- data/lib/formtastic/inputs/base/wrapping.rb +29 -26
- data/lib/formtastic/inputs/base.rb +22 -15
- data/lib/formtastic/inputs/boolean_input.rb +26 -12
- data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
- data/lib/formtastic/inputs/color_input.rb +41 -0
- data/lib/formtastic/inputs/country_input.rb +24 -5
- data/lib/formtastic/inputs/datalist_input.rb +41 -0
- data/lib/formtastic/inputs/date_picker_input.rb +93 -0
- data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
- data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
- data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
- data/lib/formtastic/inputs/file_input.rb +2 -2
- data/lib/formtastic/inputs/hidden_input.rb +2 -6
- data/lib/formtastic/inputs/radio_input.rb +28 -22
- data/lib/formtastic/inputs/select_input.rb +36 -39
- data/lib/formtastic/inputs/time_picker_input.rb +99 -0
- data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
- data/lib/formtastic/inputs/time_zone_input.rb +16 -6
- data/lib/formtastic/inputs.rb +32 -21
- data/lib/formtastic/localized_string.rb +1 -1
- data/lib/formtastic/localizer.rb +24 -24
- data/lib/formtastic/namespaced_class_finder.rb +99 -0
- data/lib/formtastic/version.rb +1 -1
- data/lib/formtastic.rb +20 -10
- data/lib/generators/formtastic/form/form_generator.rb +10 -4
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/formtastic/install/install_generator.rb +5 -19
- data/lib/generators/templates/_form.html.slim +2 -2
- data/lib/generators/templates/formtastic.rb +46 -25
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +23 -3
- data/script/integration-template.rb +74 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +12 -0
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +92 -56
- data/spec/actions/input_action_spec.rb +7 -7
- data/spec/actions/link_action_spec.rb +10 -10
- data/spec/builder/custom_builder_spec.rb +36 -20
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +28 -29
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
- data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
- data/spec/helpers/action_helper_spec.rb +75 -103
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +84 -33
- data/spec/helpers/input_helper_spec.rb +333 -285
- data/spec/helpers/inputs_helper_spec.rb +167 -121
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
- data/spec/i18n_spec.rb +26 -26
- data/spec/input_class_finder_spec.rb +10 -0
- data/spec/inputs/base/collections_spec.rb +76 -0
- data/spec/inputs/base/validations_spec.rb +480 -0
- data/spec/inputs/boolean_input_spec.rb +100 -65
- data/spec/inputs/check_boxes_input_spec.rb +200 -101
- data/spec/inputs/color_input_spec.rb +85 -0
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +3 -4
- data/spec/inputs/datalist_input_spec.rb +61 -0
- data/spec/inputs/date_picker_input_spec.rb +449 -0
- data/spec/inputs/date_select_input_spec.rb +249 -0
- data/spec/inputs/datetime_picker_input_spec.rb +490 -0
- data/spec/inputs/datetime_select_input_spec.rb +209 -0
- data/spec/inputs/email_input_spec.rb +5 -5
- data/spec/inputs/file_input_spec.rb +6 -6
- data/spec/inputs/hidden_input_spec.rb +22 -35
- data/spec/inputs/include_blank_spec.rb +11 -11
- data/spec/inputs/label_spec.rb +62 -25
- data/spec/inputs/number_input_spec.rb +112 -112
- data/spec/inputs/password_input_spec.rb +5 -5
- data/spec/inputs/phone_input_spec.rb +5 -5
- data/spec/inputs/placeholder_spec.rb +6 -6
- data/spec/inputs/radio_input_spec.rb +99 -55
- data/spec/inputs/range_input_spec.rb +66 -66
- data/spec/inputs/readonly_spec.rb +50 -0
- data/spec/inputs/search_input_spec.rb +5 -5
- data/spec/inputs/select_input_spec.rb +170 -170
- data/spec/inputs/string_input_spec.rb +68 -16
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +455 -0
- data/spec/inputs/time_select_input_spec.rb +261 -0
- data/spec/inputs/time_zone_input_spec.rb +54 -28
- data/spec/inputs/url_input_spec.rb +5 -5
- data/spec/inputs/with_options_spec.rb +7 -7
- data/spec/localizer_spec.rb +39 -17
- data/spec/namespaced_class_finder_spec.rb +79 -0
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +254 -221
- data/spec/support/custom_macros.rb +128 -95
- data/spec/support/shared_examples.rb +12 -0
- data/spec/support/specialized_class_finder_shared_example.rb +27 -0
- data/spec/support/test_environment.rb +26 -10
- metadata +177 -238
- data/.travis.yml +0 -8
- data/Appraisals +0 -11
- data/CHANGELOG +0 -371
- data/gemfiles/rails-3.0.gemfile +0 -7
- data/gemfiles/rails-3.1.gemfile +0 -7
- data/gemfiles/rails-3.2.gemfile +0 -7
- data/lib/formtastic/helpers/buttons_helper.rb +0 -310
- data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
- data/lib/formtastic/util.rb +0 -25
- data/lib/tasks/verify_rcov.rb +0 -44
- data/spec/helpers/buttons_helper_spec.rb +0 -166
- data/spec/helpers/commit_button_helper_spec.rb +0 -530
- data/spec/inputs/date_input_spec.rb +0 -227
- data/spec/inputs/datetime_input_spec.rb +0 -185
- data/spec/inputs/time_input_spec.rb +0 -267
- data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -1,23 +1,31 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
17
|
+
## Compatibility
|
9
18
|
|
10
|
-
* Formtastic
|
11
|
-
* Formtastic
|
12
|
-
* Formtastic
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
63
|
+
## It's awesome because...
|
56
64
|
|
57
|
-
* It can handle
|
58
|
-
* It can handle
|
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
|
-
|
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
|
-
|
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
|
-
|
88
|
-
gem 'formtastic'
|
89
|
-
|
90
|
+
```ruby
|
91
|
+
gem 'formtastic', '~> 4.0'
|
92
|
+
```
|
90
93
|
|
91
94
|
Run the installation generator:
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
+
```shell
|
97
|
+
$ rails generate formtastic:install
|
98
|
+
```
|
96
99
|
|
97
100
|
|
98
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
121
|
+
```
|
130
122
|
|
131
|
-
|
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
|
-
|
137
|
-
|
128
|
+
```
|
138
129
|
|
130
|
+
```ruby
|
131
|
+
# config/environments/production.rb
|
132
|
+
config.assets.precompile += %w( ie6.css ie7.css )
|
133
|
+
```
|
139
134
|
|
140
|
-
|
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
|
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
|
-
|
141
|
+
```erb
|
147
142
|
<%= semantic_form_for @user do |f| %>
|
148
143
|
<%= f.inputs %>
|
149
144
|
<%= f.actions %>
|
150
145
|
<% end %>
|
151
|
-
|
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
|
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
|
-
|
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
|
-
|
157
|
+
```
|
163
158
|
|
164
|
-
You probably want control over the input type Formtastic uses for each field. You can expand the
|
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
|
-
|
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
|
-
|
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
|
-
|
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"
|
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
|
-
|
196
|
+
```
|
202
197
|
|
203
198
|
You can create forms for nested resources:
|
204
199
|
|
205
|
-
|
200
|
+
```erb
|
206
201
|
<%= semantic_form_for [@author, @post] do |f| %>
|
207
|
-
|
202
|
+
```
|
208
203
|
|
209
|
-
Nested forms are also supported (don't forget your models need to be setup correctly with
|
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
|
-
|
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
|
-
|
214
|
+
```
|
220
215
|
|
221
|
-
Or the Formtastic way with the
|
216
|
+
Or the Formtastic way with the `:for` option:
|
222
217
|
|
223
|
-
|
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
|
-
|
224
|
+
```
|
230
225
|
|
231
|
-
When working in has many association, you can even supply
|
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
|
-
|
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
|
-
|
234
|
+
```
|
240
235
|
|
241
236
|
Alternatively, the current index can be accessed via the `inputs` block's arguments for use anywhere:
|
242
237
|
|
243
|
-
|
238
|
+
```erb
|
244
239
|
<%= semantic_form_for @post do |f| %>
|
245
240
|
<%= f.inputs :for => :categories do |category, i| %>
|
246
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
257
|
+
```
|
268
258
|
|
269
|
-
Customize HTML attributes for any input using the
|
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
|
-
|
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
|
-
|
271
|
+
```
|
282
272
|
|
283
|
-
The same can be done for actions with the
|
273
|
+
The same can be done for actions with the `:button_html` option:
|
284
274
|
|
285
|
-
|
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
|
-
|
282
|
+
```
|
293
283
|
|
294
|
-
Customize the HTML attributes for the
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
320
|
-
f.input :authors, :as => :check_boxes, :collection => User.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
320
|
+
## The Available Inputs
|
336
321
|
|
337
322
|
The Formtastic input types:
|
338
323
|
|
339
|
-
*
|
340
|
-
*
|
341
|
-
*
|
342
|
-
*
|
343
|
-
*
|
344
|
-
*
|
345
|
-
*
|
346
|
-
*
|
347
|
-
*
|
348
|
-
*
|
349
|
-
*
|
350
|
-
*
|
351
|
-
*
|
352
|
-
*
|
353
|
-
*
|
354
|
-
*
|
355
|
-
*
|
356
|
-
*
|
357
|
-
*
|
358
|
-
*
|
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
|
-
|
349
|
+
## Delegation for label lookups
|
364
350
|
|
365
351
|
Formtastic decides which label to use in the following order:
|
366
352
|
|
367
|
-
|
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
|
-
|
357
|
+
4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
|
358
|
+
```
|
373
359
|
|
374
|
-
|
360
|
+
## Internationalization (I18n)
|
375
361
|
|
376
|
-
|
362
|
+
### Basic Localization
|
377
363
|
|
378
|
-
Formtastic has some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling
|
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
|
-
|
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
|
-
|
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
|
-
|
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 (
|
384
|
+
*1. Enable I18n lookups by default (`config/initializers/formtastic.rb`):*
|
399
385
|
|
400
|
-
|
386
|
+
```ruby
|
401
387
|
Formtastic::FormBuilder.i18n_lookups_by_default = true
|
402
|
-
|
388
|
+
```
|
403
389
|
|
404
|
-
*2. Add some
|
390
|
+
*2. Add some label-translations/variants (`config/locales/en.yml`):*
|
405
391
|
|
406
|
-
|
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
|
-
|
419
|
+
```
|
434
420
|
|
435
421
|
*3. ...and now you'll get:*
|
436
422
|
|
437
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
447
|
+
```
|
462
448
|
|
463
449
|
*5. Override I18n settings:*
|
464
450
|
|
465
|
-
|
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
|
-
|
462
|
+
```
|
477
463
|
|
478
464
|
If I18n-lookups is disabled, i.e.:
|
479
465
|
|
480
|
-
|
466
|
+
```ruby
|
481
467
|
Formtastic::FormBuilder.i18n_lookups_by_default = false
|
482
|
-
|
468
|
+
```
|
483
469
|
|
484
470
|
...then you can enable I18n within the forms instead:
|
485
471
|
|
486
|
-
|
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
|
-
|
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
|
-
*
|
504
|
-
*
|
505
|
-
*
|
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.
|
510
|
-
2.
|
511
|
-
3.
|
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
|
-
|
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
|
-
|
515
|
+
```
|
530
516
|
|
531
|
-
Values for
|
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
|
-
|
522
|
+
## Semantic errors
|
535
523
|
|
536
|
-
You can show errors on base (by default) and any other attribute just passing
|
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
|
-
|
526
|
+
```erb
|
539
527
|
<%= semantic_form_for @post do |f| %>
|
540
528
|
<%= f.semantic_errors :state %>
|
541
529
|
<% end %>
|
542
|
-
|
530
|
+
```
|
543
531
|
|
544
532
|
|
545
|
-
|
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
|
-
*
|
550
|
-
*
|
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
|
-
|
542
|
+
### Changing Existing Input Behavior
|
556
543
|
|
557
|
-
To modify the behavior of
|
544
|
+
To modify the behavior of `StringInput`, subclass it in a new file, `app/inputs/string_input.rb`:
|
558
545
|
|
559
|
-
|
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
|
-
|
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
|
562
|
+
You can use your modified version with `:as => :string`.
|
569
563
|
|
570
|
-
|
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
|
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
|
-
|
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
|
-
|
574
|
+
```
|
581
575
|
|
582
|
-
You can
|
576
|
+
You can also extend existing input behavior by using the input generator:
|
583
577
|
|
584
|
-
|
578
|
+
```shell
|
579
|
+
$ rails generate formtastic:input FlexibleText --extend string
|
580
|
+
```
|
585
581
|
|
586
|
-
|
582
|
+
This generates the file `app/inputs/flexible_text_input.rb` with its respective content class.
|
587
583
|
|
588
|
-
|
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
|
-
|
596
|
-
|
597
|
-
You can use your new input with @:as => :date_picker@.
|
597
|
+
```
|
598
598
|
|
599
|
-
|
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
|
-
|
604
|
+
There are none other than Rails itself, but...
|
605
605
|
|
606
|
-
|
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
|
-
*
|
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
|
-
|
620
|
+
## Project Info
|
635
621
|
|
636
|
-
|
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
|
-
|
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
|
-
|
626
|
+
Copyright (c) 2007-2021, released under the MIT license.
|
641
627
|
|
642
|
-
Copyright (c) 2007-2012 Justin French, released under the MIT license.
|