formtastic 3.1.2 → 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 +3 -2
- data/CHANGELOG.md +52 -0
- data/Gemfile.lock +105 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +178 -167
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +20 -1
- data/app/assets/stylesheets/formtastic.css +1 -1
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +10 -16
- 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.rb +9 -11
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +1 -38
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +11 -24
- data/lib/formtastic/helpers.rb +1 -1
- data/lib/formtastic/helpers/action_helper.rb +1 -48
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +13 -9
- data/lib/formtastic/helpers/form_helper.rb +1 -1
- data/lib/formtastic/helpers/input_helper.rb +23 -77
- data/lib/formtastic/helpers/inputs_helper.rb +27 -22
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/inputs.rb +32 -29
- data/lib/formtastic/inputs/base/choices.rb +1 -1
- data/lib/formtastic/inputs/base/collections.rb +43 -10
- data/lib/formtastic/inputs/base/database.rb +7 -2
- data/lib/formtastic/inputs/base/errors.rb +4 -4
- data/lib/formtastic/inputs/base/hints.rb +1 -1
- data/lib/formtastic/inputs/base/html.rb +7 -6
- data/lib/formtastic/inputs/base/naming.rb +4 -4
- data/lib/formtastic/inputs/base/options.rb +2 -3
- data/lib/formtastic/inputs/base/timeish.rb +5 -1
- data/lib/formtastic/inputs/base/validations.rb +38 -12
- data/lib/formtastic/inputs/check_boxes_input.rb +13 -5
- data/lib/formtastic/inputs/color_input.rb +0 -1
- data/lib/formtastic/inputs/country_input.rb +3 -1
- data/lib/formtastic/inputs/radio_input.rb +20 -0
- data/lib/formtastic/inputs/select_input.rb +29 -1
- data/lib/formtastic/inputs/time_zone_input.rb +16 -6
- data/lib/formtastic/localizer.rb +20 -22
- data/lib/formtastic/namespaced_class_finder.rb +1 -1
- data/lib/formtastic/version.rb +1 -1
- data/lib/generators/formtastic/form/form_generator.rb +1 -1
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/templates/formtastic.rb +14 -13
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +1 -1
- data/script/integration-template.rb +74 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +1 -1
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +60 -60
- 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 +37 -21
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +27 -27
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +25 -25
- 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 +328 -10
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +37 -37
- data/spec/helpers/input_helper_spec.rb +975 -2
- data/spec/helpers/inputs_helper_spec.rb +120 -105
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +22 -22
- data/spec/i18n_spec.rb +26 -26
- data/spec/input_class_finder_spec.rb +1 -1
- 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 +55 -55
- data/spec/inputs/check_boxes_input_spec.rb +155 -108
- data/spec/inputs/color_input_spec.rb +51 -63
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +2 -6
- data/spec/inputs/datalist_input_spec.rb +1 -1
- data/spec/inputs/date_picker_input_spec.rb +42 -42
- data/spec/inputs/date_select_input_spec.rb +51 -37
- data/spec/inputs/datetime_picker_input_spec.rb +46 -46
- data/spec/inputs/datetime_select_input_spec.rb +53 -37
- 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 +18 -18
- data/spec/inputs/include_blank_spec.rb +8 -8
- data/spec/inputs/label_spec.rb +20 -20
- 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 +5 -5
- data/spec/inputs/radio_input_spec.rb +84 -58
- 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 +149 -93
- data/spec/inputs/string_input_spec.rb +23 -23
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +43 -43
- data/spec/inputs/time_select_input_spec.rb +67 -54
- 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 +17 -17
- data/spec/namespaced_class_finder_spec.rb +2 -2
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +165 -253
- data/spec/support/custom_macros.rb +72 -75
- data/spec/support/shared_examples.rb +0 -1232
- data/spec/support/test_environment.rb +23 -9
- metadata +69 -176
- data/.travis.yml +0 -29
- data/Appraisals +0 -29
- data/CHANGELOG +0 -31
- data/DEPRECATIONS +0 -49
- data/gemfiles/rails_3.2.gemfile +0 -7
- data/gemfiles/rails_4.0.4.gemfile +0 -7
- data/gemfiles/rails_4.1.gemfile +0 -7
- data/gemfiles/rails_4.2.gemfile +0 -7
- data/gemfiles/rails_4.gemfile +0 -7
- data/gemfiles/rails_edge.gemfile +0 -10
- data/lib/formtastic/util.rb +0 -57
- data/spec/helpers/namespaced_action_helper_spec.rb +0 -43
- data/spec/helpers/namespaced_input_helper_spec.rb +0 -36
- data/spec/support/deferred_garbage_collection.rb +0 -21
- data/spec/util_spec.rb +0 -66
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cb44ea01df970135604cdddd0ac7b762ea56077f915810c4c8fe6be3487cafa3
|
4
|
+
data.tar.gz: 18630a8282b76e40d0c6e9faad19f99112dfd9e22ba22e7b025d8730ebf26ace
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73a3ad17e91765150e4e15e03d3031f5b9efd975a09bbb21c7f404709b7d2462e9cf16c708beaf2745b783def3a631ca1b3bd47278d79c16012d79ba1f549fc0
|
7
|
+
data.tar.gz: d418a7e65f928dedfd36627c3ece7c4fe7e371984500ddc4bcb6c5929087264541476c469be6520270000a0e8348bc2cd41415e94d46c86da2e48021bf54d4be
|
data/.gitattributes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
CHANGELOG merge=union
|
@@ -0,0 +1,61 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
test:
|
9
|
+
runs-on: ubuntu-20.04
|
10
|
+
|
11
|
+
strategy:
|
12
|
+
fail-fast: false
|
13
|
+
|
14
|
+
matrix:
|
15
|
+
gemfile:
|
16
|
+
- gemfiles/rails_5.2/Gemfile
|
17
|
+
- gemfiles/rails_6.0/Gemfile
|
18
|
+
- gemfiles/rails_6.1/Gemfile
|
19
|
+
- gemfiles/rails_edge/Gemfile
|
20
|
+
|
21
|
+
ruby:
|
22
|
+
- 2.4.10
|
23
|
+
- 2.5.8
|
24
|
+
- 2.6.6
|
25
|
+
- 2.7.2
|
26
|
+
- 3.0.0
|
27
|
+
|
28
|
+
exclude:
|
29
|
+
- ruby: 2.4.10
|
30
|
+
gemfile: gemfiles/rails_6.0/Gemfile
|
31
|
+
|
32
|
+
- ruby: 2.4.10
|
33
|
+
gemfile: gemfiles/rails_6.1/Gemfile
|
34
|
+
|
35
|
+
- ruby: 2.4.10
|
36
|
+
gemfile: gemfiles/rails_edge/Gemfile
|
37
|
+
|
38
|
+
- ruby: 3.0.0
|
39
|
+
gemfile: gemfiles/rails_5.2/Gemfile
|
40
|
+
|
41
|
+
env:
|
42
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
43
|
+
|
44
|
+
steps:
|
45
|
+
- uses: actions/checkout@v2
|
46
|
+
|
47
|
+
- uses: actions/setup-node@v2
|
48
|
+
with:
|
49
|
+
node-version: 11
|
50
|
+
|
51
|
+
- name: Set up Ruby
|
52
|
+
uses: ruby/setup-ruby@v1
|
53
|
+
with:
|
54
|
+
ruby-version: ${{ matrix.ruby }}
|
55
|
+
bundler-cache: true
|
56
|
+
|
57
|
+
- name: Run tests
|
58
|
+
run: |
|
59
|
+
bundle exec rake spec
|
60
|
+
script/integration.sh
|
61
|
+
continue-on-error: ${{ matrix.gemfile == 'gemfiles/rails_edge/Gemfile' }}
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
## master / 4.0.0
|
2
|
+
* Fixed default_columns_for_object when object has non-standard foreign keys (#1241)
|
3
|
+
* Fixed missing constants in production (#911)
|
4
|
+
* Removed support for Rails 3 and 4.0 (#1108)
|
5
|
+
* Removed deprecated input/action finder methods (#1139)
|
6
|
+
* Changed boolean label padding to margin (#1202)
|
7
|
+
* Added mapping hstore column to text input (#1203)
|
8
|
+
* Added support for Rails 5 Attributes API (#1188)
|
9
|
+
* Changed required Ruby version to >= 2.0 (#1210)
|
10
|
+
* Default to input types text for json & jsonb, string for citext columns (#1229)
|
11
|
+
* Allow symbols for numericality options (#1258)
|
12
|
+
* Support for rubies under 2.4.0 has been dropped (#1292)
|
13
|
+
* Support for Rails under 5.2.0 has been dropped (#1293)
|
14
|
+
* Support for Rails 6.0 has been added (#1300)
|
15
|
+
* Support for Rails 6.1 has been added (#1324)
|
16
|
+
* Support for Ruby 3 has been added (#1323)
|
17
|
+
|
18
|
+
## 3.1.2
|
19
|
+
|
20
|
+
* Fixed that we specified 4.0.4 instead of 4.1 in the Rails version deprecation message
|
21
|
+
|
22
|
+
## 3.1.1
|
23
|
+
|
24
|
+
* Fixed class custom input & action class loading in test environments
|
25
|
+
* Added documentation of custom input & action class finders
|
26
|
+
* Added a link to documentation & wiki from custom class deprecation warnings
|
27
|
+
|
28
|
+
## 3.1.0
|
29
|
+
|
30
|
+
* Performance and documentation improvements
|
31
|
+
|
32
|
+
## 3.1.0.rc2
|
33
|
+
|
34
|
+
* Deprecated :member_value and :member_label options
|
35
|
+
|
36
|
+
## 3.1.0.rc1
|
37
|
+
|
38
|
+
* Deprecated support for Rails version < 4.1.0
|
39
|
+
* Fixed synchronization issues with custom_namespace configuration
|
40
|
+
* Fixed bug where boolean (checkbox) inputs were not being correctly checked (also in 2.3.1)
|
41
|
+
* Fixed (silenced) Rails 5 deprecation on column_for_attribute that we're handling fine
|
42
|
+
* Added new DatalistInput (:as => :datalist) for HTML5 datalists
|
43
|
+
* Added configurable namespaces for custom inputs
|
44
|
+
* Various performance and documentation improvements
|
45
|
+
|
46
|
+
---
|
47
|
+
|
48
|
+
See 3.0-stable branch for 3.0.x changes
|
49
|
+
https://github.com/formtastic/formtastic/blob/3.0-stable/CHANGELOG
|
50
|
+
|
51
|
+
See 2.3-stable branch for 2.3.x and earlier releases
|
52
|
+
https://github.com/formtastic/formtastic/blob/2.3-stable/CHANGELOG
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
formtastic (4.0.0.rc1)
|
5
|
+
actionpack (>= 5.2.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionpack (6.1.1)
|
11
|
+
actionview (= 6.1.1)
|
12
|
+
activesupport (= 6.1.1)
|
13
|
+
rack (~> 2.0, >= 2.0.9)
|
14
|
+
rack-test (>= 0.6.3)
|
15
|
+
rails-dom-testing (~> 2.0)
|
16
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
17
|
+
actionview (6.1.1)
|
18
|
+
activesupport (= 6.1.1)
|
19
|
+
builder (~> 3.1)
|
20
|
+
erubi (~> 1.4)
|
21
|
+
rails-dom-testing (~> 2.0)
|
22
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
23
|
+
activesupport (6.1.1)
|
24
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
25
|
+
i18n (>= 1.6, < 2)
|
26
|
+
minitest (>= 5.1)
|
27
|
+
tzinfo (~> 2.0)
|
28
|
+
zeitwerk (~> 2.3)
|
29
|
+
ammeter (1.1.4)
|
30
|
+
activesupport (>= 3.0)
|
31
|
+
railties (>= 3.0)
|
32
|
+
rspec-rails (>= 2.2)
|
33
|
+
builder (3.2.4)
|
34
|
+
concurrent-ruby (1.1.8)
|
35
|
+
crass (1.0.6)
|
36
|
+
diff-lcs (1.3)
|
37
|
+
erubi (1.10.0)
|
38
|
+
i18n (1.8.7)
|
39
|
+
concurrent-ruby (~> 1.0)
|
40
|
+
loofah (2.9.0)
|
41
|
+
crass (~> 1.0.2)
|
42
|
+
nokogiri (>= 1.5.9)
|
43
|
+
method_source (1.0.0)
|
44
|
+
mini_portile2 (2.5.0)
|
45
|
+
minitest (5.14.3)
|
46
|
+
nokogiri (1.11.1)
|
47
|
+
mini_portile2 (~> 2.5.0)
|
48
|
+
racc (~> 1.4)
|
49
|
+
racc (1.5.2)
|
50
|
+
rack (2.2.3)
|
51
|
+
rack-test (1.1.0)
|
52
|
+
rack (>= 1.0, < 3)
|
53
|
+
rails-dom-testing (2.0.3)
|
54
|
+
activesupport (>= 4.2.0)
|
55
|
+
nokogiri (>= 1.6)
|
56
|
+
rails-html-sanitizer (1.3.0)
|
57
|
+
loofah (~> 2.3)
|
58
|
+
railties (6.1.1)
|
59
|
+
actionpack (= 6.1.1)
|
60
|
+
activesupport (= 6.1.1)
|
61
|
+
method_source
|
62
|
+
rake (>= 0.8.7)
|
63
|
+
thor (~> 1.0)
|
64
|
+
rake (13.0.3)
|
65
|
+
rspec-core (3.9.2)
|
66
|
+
rspec-support (~> 3.9.3)
|
67
|
+
rspec-dom-testing (0.1.0)
|
68
|
+
rails-dom-testing (>= 1.0, < 3)
|
69
|
+
rspec-expectations (~> 3.0)
|
70
|
+
rspec-expectations (3.9.2)
|
71
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
72
|
+
rspec-support (~> 3.9.0)
|
73
|
+
rspec-mocks (3.9.1)
|
74
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
75
|
+
rspec-support (~> 3.9.0)
|
76
|
+
rspec-rails (3.9.1)
|
77
|
+
actionpack (>= 3.0)
|
78
|
+
activesupport (>= 3.0)
|
79
|
+
railties (>= 3.0)
|
80
|
+
rspec-core (~> 3.9.0)
|
81
|
+
rspec-expectations (~> 3.9.0)
|
82
|
+
rspec-mocks (~> 3.9.0)
|
83
|
+
rspec-support (~> 3.9.0)
|
84
|
+
rspec-support (3.9.3)
|
85
|
+
sqlite3 (1.4.2)
|
86
|
+
thor (1.1.0)
|
87
|
+
tzinfo (2.0.4)
|
88
|
+
concurrent-ruby (~> 1.0)
|
89
|
+
yard (0.9.25)
|
90
|
+
zeitwerk (2.4.2)
|
91
|
+
|
92
|
+
PLATFORMS
|
93
|
+
ruby
|
94
|
+
|
95
|
+
DEPENDENCIES
|
96
|
+
ammeter (~> 1.1.3)
|
97
|
+
formtastic!
|
98
|
+
rake
|
99
|
+
rspec-dom-testing (>= 0.1.0)
|
100
|
+
rspec-rails (~> 3.4)
|
101
|
+
sqlite3 (~> 1.4)
|
102
|
+
yard (~> 0.9.20)
|
103
|
+
|
104
|
+
BUNDLED WITH
|
105
|
+
2.1.4
|
data/MIT-LICENSE
CHANGED
@@ -1,36 +1,31 @@
|
|
1
|
-
|
1
|
+
# Formtastic
|
2
2
|
|
3
|
-
!https://
|
4
|
-
!
|
5
|
-
!https://codeclimate.com/github/
|
6
|
-
!https://badge.fury.io/rb/formtastic.
|
7
|
-
!https://gemnasium.com/justinfrench/formtastic.png!:https://gemnasium.com/justinfrench/formtastic
|
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)
|
8
7
|
|
9
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.
|
10
9
|
|
10
|
+
## Documentation & Support
|
11
11
|
|
12
|
-
|
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)
|
13
16
|
|
14
|
-
|
15
|
-
* "We track issues & bugs on GitHub":http://github.com/justinfrench/formtastic/issues
|
16
|
-
* "We have a wiki on GitHub":http://github.com/justinfrench/formtastic/wiki
|
17
|
-
* "StackOverflow can help":http://stackoverflow.com/questions/tagged/formtastic
|
18
|
-
* "Follow @formtastic on Twitter for news & updates":http://twitter.com/formtastic
|
17
|
+
## Compatibility
|
19
18
|
|
20
|
-
|
21
|
-
h2. Compatibility
|
22
|
-
|
23
|
-
* Formtastic 4 will require Rails 4.1
|
19
|
+
* Formtastic 4 requires Rails 5.2 and Ruby 2.5 minimum
|
24
20
|
* Formtastic 3 requires Rails 3.2.13 minimum
|
25
21
|
* Formtastic 2 requires Rails 3
|
26
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!
|
27
23
|
|
28
|
-
|
29
|
-
h2. The Story
|
24
|
+
## The Story
|
30
25
|
|
31
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:
|
32
27
|
|
33
|
-
|
28
|
+
```erb
|
34
29
|
<%= semantic_form_for @article do |f| %>
|
35
30
|
|
36
31
|
<%= f.inputs :name => "Basic" do %>
|
@@ -60,15 +55,15 @@ One day, I finally had enough, so I opened up my text editor, and wrote a DSL fo
|
|
60
55
|
<% end %>
|
61
56
|
|
62
57
|
<% end %>
|
63
|
-
|
58
|
+
```
|
64
59
|
|
65
|
-
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.
|
66
61
|
|
67
62
|
|
68
|
-
|
63
|
+
## It's awesome because...
|
69
64
|
|
70
|
-
* It can handle
|
71
|
-
* It can handle
|
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.
|
72
67
|
* It's Rails 3/4 compatible (including nested forms).
|
73
68
|
* It has internationalization (I18n)!
|
74
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.
|
@@ -80,7 +75,7 @@ h2. It's awesome because...
|
|
80
75
|
* It has growing HTML5 support (new inputs like email/phone/search, new attributes like required/min/max/step/placeholder)
|
81
76
|
|
82
77
|
|
83
|
-
|
78
|
+
## Opinions
|
84
79
|
|
85
80
|
* It should be easier to do things the right way than the wrong way.
|
86
81
|
* Sometimes _more mark-up_ is better.
|
@@ -88,82 +83,82 @@ h2. Opinions
|
|
88
83
|
* Make the common things we do easy, yet ensure uncommon things are still possible.
|
89
84
|
|
90
85
|
|
91
|
-
|
86
|
+
## Installation
|
92
87
|
|
93
88
|
Simply add Formtastic to your Gemfile and bundle it up:
|
94
89
|
|
95
|
-
|
96
|
-
gem 'formtastic', '~>
|
97
|
-
|
90
|
+
```ruby
|
91
|
+
gem 'formtastic', '~> 4.0'
|
92
|
+
```
|
98
93
|
|
99
94
|
Run the installation generator:
|
100
95
|
|
101
|
-
|
102
|
-
|
103
|
-
|
96
|
+
```shell
|
97
|
+
$ rails generate formtastic:install
|
98
|
+
```
|
104
99
|
|
105
100
|
|
106
|
-
|
101
|
+
## Stylesheets
|
107
102
|
|
108
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.
|
109
104
|
|
110
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.
|
111
106
|
|
112
|
-
|
107
|
+
```css
|
113
108
|
# app/assets/stylesheets/application.css
|
114
109
|
*= require formtastic
|
115
110
|
*= require my_formtastic_changes
|
116
|
-
|
111
|
+
```
|
117
112
|
|
118
|
-
Conditional stylesheets need to be compiled separately to prevent them being bundled and included with other application styles. Remove
|
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.
|
119
114
|
|
120
|
-
|
115
|
+
```css
|
121
116
|
# app/assets/stylesheets/ie6.css
|
122
117
|
*= require formtastic_ie6
|
123
118
|
|
124
119
|
# app/assets/stylesheets/ie7.css
|
125
120
|
*= require formtastic_ie7
|
126
|
-
|
121
|
+
```
|
127
122
|
|
128
|
-
|
123
|
+
```erb
|
129
124
|
# app/views/layouts/application.html.erb
|
130
125
|
<%= stylesheet_link_tag 'application' %>
|
131
126
|
<!--[if IE 6]><%= stylesheet_link_tag 'ie6' %><![endif]-->
|
132
127
|
<!--[if IE 7]><%= stylesheet_link_tag 'ie7' %><![endif]-->
|
133
|
-
|
128
|
+
```
|
134
129
|
|
135
|
-
|
130
|
+
```ruby
|
136
131
|
# config/environments/production.rb
|
137
132
|
config.assets.precompile += %w( ie6.css ie7.css )
|
138
|
-
|
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 %>
|
@@ -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,41 +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
241
|
...
|
247
242
|
<%= f.actions %>
|
248
243
|
<% end %>
|
249
|
-
|
244
|
+
```
|
250
245
|
|
251
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:
|
252
247
|
|
253
|
-
|
248
|
+
```erb
|
254
249
|
<%= semantic_form_for(@post, :namespace => 'cat_form') do |f| %>
|
255
250
|
<%= f.inputs do %>
|
256
251
|
<%= f.input :title %> # id="cat_form_post_title"
|
@@ -259,11 +254,11 @@ If you have more than one form on the same page, it may lead to HTML invalidatio
|
|
259
254
|
<% end %>
|
260
255
|
<%= f.actions %>
|
261
256
|
<% end %>
|
262
|
-
|
257
|
+
```
|
263
258
|
|
264
|
-
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:
|
265
260
|
|
266
|
-
|
261
|
+
```erb
|
267
262
|
<%= semantic_form_for @post do |f| %>
|
268
263
|
<%= f.inputs do %>
|
269
264
|
<%= f.input :title, :input_html => { :size => 10 } %>
|
@@ -273,22 +268,22 @@ Customize HTML attributes for any input using the @:input_html@ option. Typicall
|
|
273
268
|
<% end %>
|
274
269
|
<%= f.actions %>
|
275
270
|
<% end %>
|
276
|
-
|
271
|
+
```
|
277
272
|
|
278
|
-
The same can be done for actions with the
|
273
|
+
The same can be done for actions with the `:button_html` option:
|
279
274
|
|
280
|
-
|
275
|
+
```erb
|
281
276
|
<%= semantic_form_for @post do |f| %>
|
282
277
|
...
|
283
278
|
<%= f.actions do %>
|
284
279
|
<%= f.action :submit, :button_html => { :class => "primary", :disable_with => 'Wait...' } %>
|
285
280
|
<% end %>
|
286
281
|
<% end %>
|
287
|
-
|
282
|
+
```
|
288
283
|
|
289
|
-
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"`).
|
290
285
|
|
291
|
-
|
286
|
+
```erb
|
292
287
|
<%= semantic_form_for @post do |f| %>
|
293
288
|
<%= f.inputs do %>
|
294
289
|
<%= f.input :title, :wrapper_html => { :class => "important" } %>
|
@@ -297,11 +292,11 @@ Customize the HTML attributes for the @<li>@ wrapper around every input with the
|
|
297
292
|
<% end %>
|
298
293
|
...
|
299
294
|
<% end %>
|
300
|
-
|
295
|
+
```
|
301
296
|
|
302
|
-
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:
|
303
298
|
|
304
|
-
|
299
|
+
```ruby
|
305
300
|
f.input :authors, :as => :check_boxes, :collection => User.order("last_name ASC").all
|
306
301
|
f.input :authors, :as => :check_boxes, :collection => current_user.company.users.active
|
307
302
|
f.input :authors, :as => :check_boxes, :collection => [@justin, @kate]
|
@@ -319,58 +314,58 @@ Many inputs provide a collection of options to choose from (like @:select@, @:ra
|
|
319
314
|
f.input :admin, :as => :radio, :collection => ["Yes!", "No"]
|
320
315
|
f.input :book_id, :as => :select, :collection => Hash[Book.all.map{|b| [b.name,b.id]}]
|
321
316
|
f.input :fav_book,:as => :datalist , :collection => Book.pluck(:name)
|
322
|
-
|
317
|
+
```
|
323
318
|
|
324
319
|
|
325
|
-
|
320
|
+
## The Available Inputs
|
326
321
|
|
327
322
|
The Formtastic input types:
|
328
323
|
|
329
|
-
*
|
330
|
-
*
|
331
|
-
*
|
332
|
-
*
|
333
|
-
*
|
334
|
-
*
|
335
|
-
*
|
336
|
-
*
|
337
|
-
*
|
338
|
-
*
|
339
|
-
*
|
340
|
-
*
|
341
|
-
*
|
342
|
-
*
|
343
|
-
*
|
344
|
-
*
|
345
|
-
*
|
346
|
-
*
|
347
|
-
*
|
348
|
-
*
|
349
|
-
*
|
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
|
350
345
|
|
351
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.
|
352
347
|
|
353
348
|
|
354
|
-
|
349
|
+
## Delegation for label lookups
|
355
350
|
|
356
351
|
Formtastic decides which label to use in the following order:
|
357
352
|
|
358
|
-
|
353
|
+
```
|
359
354
|
1. :label # :label => "Choose Title"
|
360
355
|
2. Formtastic i18n # if either :label => true || i18n_lookups_by_default = true (see Internationalization)
|
361
356
|
3. Activerecord i18n # if localization file found for the given attribute
|
362
357
|
4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
|
363
|
-
|
358
|
+
```
|
364
359
|
|
365
|
-
|
360
|
+
## Internationalization (I18n)
|
366
361
|
|
367
|
-
|
362
|
+
### Basic Localization
|
368
363
|
|
369
|
-
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.
|
370
365
|
|
371
366
|
Basic localization (labels only, with ActiveRecord):
|
372
367
|
|
373
|
-
|
368
|
+
```erb
|
374
369
|
<%= semantic_form_for @post do |f| %>
|
375
370
|
<%= f.inputs do %>
|
376
371
|
<%= f.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
|
@@ -378,23 +373,23 @@ Basic localization (labels only, with ActiveRecord):
|
|
378
373
|
<%= f.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
|
379
374
|
<% end %>
|
380
375
|
<% end %>
|
381
|
-
|
376
|
+
```
|
382
377
|
|
383
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?
|
384
379
|
|
385
|
-
|
380
|
+
### Enhanced Localization (Formtastic I18n API)
|
386
381
|
|
387
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:
|
388
383
|
|
389
|
-
*1. Enable I18n lookups by default (
|
384
|
+
*1. Enable I18n lookups by default (`config/initializers/formtastic.rb`):*
|
390
385
|
|
391
|
-
|
386
|
+
```ruby
|
392
387
|
Formtastic::FormBuilder.i18n_lookups_by_default = true
|
393
|
-
|
388
|
+
```
|
394
389
|
|
395
|
-
*2. Add some label-translations/variants (
|
390
|
+
*2. Add some label-translations/variants (`config/locales/en.yml`):*
|
396
391
|
|
397
|
-
|
392
|
+
```yml
|
398
393
|
en:
|
399
394
|
formtastic:
|
400
395
|
titles:
|
@@ -421,11 +416,11 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
|
|
421
416
|
reset: "Reset form"
|
422
417
|
cancel: "Cancel and go back"
|
423
418
|
dummie: "Launch!"
|
424
|
-
|
419
|
+
```
|
425
420
|
|
426
421
|
*3. ...and now you'll get:*
|
427
422
|
|
428
|
-
|
423
|
+
```erb
|
429
424
|
<%= semantic_form_for Post.new do |f| %>
|
430
425
|
<%= f.inputs do %>
|
431
426
|
<%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
|
@@ -436,24 +431,24 @@ Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the
|
|
436
431
|
<%= f.action :submit %> # => "Create my %{model}"
|
437
432
|
<% end %>
|
438
433
|
<% end %>
|
439
|
-
|
434
|
+
```
|
440
435
|
|
441
436
|
*4. Localized titles (a.k.a. legends):*
|
442
437
|
|
443
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._
|
444
439
|
|
445
|
-
|
440
|
+
```erb
|
446
441
|
<%= semantic_form_for @post do |f| %>
|
447
442
|
<%= f.inputs :post_details do %> # => :title => "Post details"
|
448
443
|
# ...
|
449
444
|
<% end %>
|
450
445
|
# ...
|
451
446
|
<% end %>
|
452
|
-
|
447
|
+
```
|
453
448
|
|
454
449
|
*5. Override I18n settings:*
|
455
450
|
|
456
|
-
|
451
|
+
```erb
|
457
452
|
<%= semantic_form_for @post do |f| %>
|
458
453
|
<%= f.inputs do %>
|
459
454
|
<%= f.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for your post."
|
@@ -464,17 +459,17 @@ _Note: Slightly different because Formtastic can't guess how you group fields in
|
|
464
459
|
<%= f.action :submit, :label => :dummie %> # => "Launch!"
|
465
460
|
<% end %>
|
466
461
|
<% end %>
|
467
|
-
|
462
|
+
```
|
468
463
|
|
469
464
|
If I18n-lookups is disabled, i.e.:
|
470
465
|
|
471
|
-
|
466
|
+
```ruby
|
472
467
|
Formtastic::FormBuilder.i18n_lookups_by_default = false
|
473
|
-
|
468
|
+
```
|
474
469
|
|
475
470
|
...then you can enable I18n within the forms instead:
|
476
471
|
|
477
|
-
|
472
|
+
```erb
|
478
473
|
<%= semantic_form_for @post do |f| %>
|
479
474
|
<%= f.inputs do %>
|
480
475
|
<%= f.input :title, :label => true %> # => :label => "Choose a title..."
|
@@ -485,25 +480,25 @@ If I18n-lookups is disabled, i.e.:
|
|
485
480
|
<%= f.action :submit, :label => true %> # => "Update %{model}" (if we are in edit that is...)
|
486
481
|
<% end %>
|
487
482
|
<% end %>
|
488
|
-
|
483
|
+
```
|
489
484
|
|
490
485
|
*6. Advanced I18n lookups*
|
491
486
|
|
492
487
|
For more flexible forms; Formtastic finds translations using a bottom-up approach taking the following variables in account:
|
493
488
|
|
494
|
-
*
|
495
|
-
*
|
496
|
-
*
|
489
|
+
* `MODEL`, e.g. "post"
|
490
|
+
* `ACTION`, e.g. "edit"
|
491
|
+
* `KEY/ATTRIBUTE`, e.g. "title", :my_custom_key, ...
|
497
492
|
|
498
493
|
...in the following order:
|
499
494
|
|
500
|
-
1.
|
501
|
-
2.
|
502
|
-
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
|
503
498
|
|
504
499
|
...which means that you can define translations like this:
|
505
500
|
|
506
|
-
|
501
|
+
```yml
|
507
502
|
en:
|
508
503
|
formtastic:
|
509
504
|
labels:
|
@@ -517,100 +512,116 @@ For more flexible forms; Formtastic finds translations using a bottom-up approac
|
|
517
512
|
edit:
|
518
513
|
title: "Edit title"
|
519
514
|
body: "Edit body"
|
520
|
-
|
515
|
+
```
|
521
516
|
|
522
|
-
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.
|
523
518
|
|
524
519
|
*7. Basic Translations*
|
525
|
-
If you want some basic translations, take a look on the
|
520
|
+
If you want some basic translations, take a look on the [formtastic_i18n gem](https://github.com/timoschilling/formtastic_i18n).
|
526
521
|
|
527
|
-
|
522
|
+
## Semantic errors
|
528
523
|
|
529
524
|
You can show errors on base (by default) and any other attribute just by passing its name to the semantic_errors method:
|
530
525
|
|
531
|
-
|
526
|
+
```erb
|
532
527
|
<%= semantic_form_for @post do |f| %>
|
533
528
|
<%= f.semantic_errors :state %>
|
534
529
|
<% end %>
|
535
|
-
|
530
|
+
```
|
536
531
|
|
537
532
|
|
538
|
-
|
533
|
+
## Modified & Custom Inputs
|
539
534
|
|
540
535
|
You can modify existing inputs, subclass them, or create your own from scratch. Here's the basic process:
|
541
536
|
|
542
|
-
*
|
543
|
-
*
|
544
|
-
* 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)`
|
545
539
|
|
546
540
|
Specific examples follow.
|
547
541
|
|
548
|
-
|
542
|
+
### Changing Existing Input Behavior
|
549
543
|
|
550
|
-
To modify the behavior of
|
544
|
+
To modify the behavior of `StringInput`, subclass it in a new file, `app/inputs/string_input.rb`:
|
551
545
|
|
552
|
-
|
546
|
+
```ruby
|
553
547
|
class StringInput < Formtastic::Inputs::StringInput
|
554
548
|
def to_html
|
555
549
|
puts "this is my modified version of StringInput"
|
556
550
|
super
|
557
551
|
end
|
558
552
|
end
|
559
|
-
|
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.
|
560
561
|
|
561
|
-
You can use your modified version with
|
562
|
+
You can use your modified version with `:as => :string`.
|
562
563
|
|
563
|
-
|
564
|
+
### Creating New Inputs Based on Existing Ones
|
564
565
|
|
565
|
-
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`:
|
566
567
|
|
567
|
-
|
568
|
+
```ruby
|
568
569
|
class FlexibleTextInput < Formtastic::Inputs::StringInput
|
569
570
|
def input_html_options
|
570
571
|
super.merge(:class => "flexible-text-area")
|
571
572
|
end
|
572
573
|
end
|
573
|
-
|
574
|
+
```
|
574
575
|
|
575
|
-
You can
|
576
|
+
You can also extend existing input behavior by using the input generator:
|
576
577
|
|
577
|
-
|
578
|
+
```shell
|
579
|
+
$ rails generate formtastic:input FlexibleText --extend string
|
580
|
+
```
|
578
581
|
|
579
|
-
|
582
|
+
This generates the file `app/inputs/flexible_text_input.rb` with its respective content class.
|
580
583
|
|
581
|
-
|
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
|
582
591
|
class DatePickerInput
|
583
592
|
include Formtastic::Inputs::Base
|
584
593
|
def to_html
|
585
594
|
# ...
|
586
595
|
end
|
587
596
|
end
|
588
|
-
|
597
|
+
```
|
589
598
|
|
590
|
-
You can use your new input with
|
599
|
+
You can use your new input with `:as => :date_picker`.
|
591
600
|
|
592
601
|
|
593
|
-
|
602
|
+
## Dependencies
|
594
603
|
|
595
604
|
There are none other than Rails itself, but...
|
596
605
|
|
597
|
-
* If you want to use the
|
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.
|
598
607
|
* There are a bunch of development dependencies if you plan to contribute to Formtastic
|
599
608
|
|
600
609
|
|
601
|
-
|
610
|
+
## How to contribute
|
602
611
|
|
603
612
|
* Fork the project on Github
|
613
|
+
* Install development dependencies (`bundle install` and `bin/appraisal install`)
|
604
614
|
* Create a topic branch for your changes
|
605
615
|
* Ensure that you provide *documentation* and *test coverage* for your changes (patches won't be accepted without)
|
606
616
|
* Ensure that all tests pass (`bundle exec rake`)
|
607
617
|
* Create a pull request on Github (these are also a great place to start a conversation around a patch as early as possible)
|
608
618
|
|
609
619
|
|
610
|
-
|
620
|
+
## Project Info
|
621
|
+
|
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.
|
611
623
|
|
612
|
-
|
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.
|
613
625
|
|
614
|
-
|
626
|
+
Copyright (c) 2007-2021, released under the MIT license.
|
615
627
|
|
616
|
-
Copyright (c) 2007-2014 Justin French, released under the MIT license.
|