simple_form 3.1.0 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/MIT-LICENSE +1 -1
- data/README.md +49 -14
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +1 -2
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +14 -1
- data/lib/simple_form/components/html5.rb +4 -4
- data/lib/simple_form/components/labels.rb +1 -1
- data/lib/simple_form/form_builder.rb +4 -3
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +1 -1
- data/lib/simple_form/inputs/date_time_input.rb +12 -8
- data/lib/simple_form/version.rb +1 -1
- data/test/form_builder/error_test.rb +8 -8
- data/test/form_builder/general_test.rb +18 -7
- data/test/form_builder/input_field_test.rb +32 -66
- data/test/form_builder/label_test.rb +12 -2
- data/test/form_builder/wrapper_test.rb +11 -11
- data/test/inputs/datetime_input_test.rb +5 -0
- data/test/inputs/required_test.rb +12 -0
- data/test/inputs/text_input_test.rb +7 -0
- data/test/support/misc_helpers.rb +8 -1
- data/test/test_helper.rb +4 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e30c2408e03c6ec8e50e4c96eb6b6ed2496c2c17
|
4
|
+
data.tar.gz: 324665062b839154b5c7b2c2fd8d2a603466c854
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b58ac3394c6237e862f81de9eae3c8511d72a27f3e65ec4c11929f6e30f52378ff325a5c7a336f18015d5707f8bce061e797c264b8fc4a15b95e653f1c8613c
|
7
|
+
data.tar.gz: 81e743325007ec095390aac7762bfe62c7ac5e0f1650a133db3834faa8303931b6e287acf5f4ed191241e3d50b9afa1d0aeba68dc43c6d0ae4229fdd27a1b94d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
## master
|
2
|
+
|
3
|
+
## enhancements
|
4
|
+
|
5
|
+
## bug fix
|
6
|
+
|
7
|
+
## 3.1.1
|
8
|
+
|
9
|
+
### enhancements
|
10
|
+
* Add the `disabled_class` to the label when the input is disabled. [@rhodrid](https://github.com/rhodrid)
|
11
|
+
|
12
|
+
### bug fix
|
13
|
+
* Make it possible to override `required` value that was previously set in the wrapper. [@nashby](https://github.com/nashby)
|
14
|
+
|
15
|
+
* `date/time/datetime` inputs now correctly generate the label `for` attribute when
|
16
|
+
HTML5 compatibility is explicitly enabled. [@ericsullivan](https://github.com/ericsullivan)
|
17
|
+
|
18
|
+
* The datetime, date, and time inputs now have a nice format by default on bootstrap.
|
19
|
+
[ulissesalmeida](https://github.com/ulissesalmeida) [eltonchrls](https://github.com/eltonchrls)
|
20
|
+
|
21
|
+
* Now it is possible to set custom input mappings for collections.
|
22
|
+
|
23
|
+
Example:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# On configuration:
|
27
|
+
config.input_mappings = { /gender$/ => :check_boxes }
|
28
|
+
|
29
|
+
# On form:
|
30
|
+
f.input :gender, collection: [:male, :female]
|
31
|
+
```
|
32
|
+
[strangeworks](https://github.com/strangeworks)
|
33
|
+
|
1
34
|
## 3.1.0
|
2
35
|
|
3
36
|
### enhancements
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2009-
|
1
|
+
Copyright (c) 2009-2015 Plataformatec http://plataformatec.com.br/
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -32,13 +32,6 @@ Run the generator:
|
|
32
32
|
rails generate simple_form:install
|
33
33
|
```
|
34
34
|
|
35
|
-
Also, if you want to use the country select, you will need the
|
36
|
-
[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
|
37
|
-
|
38
|
-
```ruby
|
39
|
-
gem 'country_select'
|
40
|
-
```
|
41
|
-
|
42
35
|
### Bootstrap
|
43
36
|
|
44
37
|
**Simple Form** can be easily integrated to the [Bootstrap](http://getbootstrap.com/).
|
@@ -70,6 +63,22 @@ You will need to provide your own CSS styles for hints.
|
|
70
63
|
|
71
64
|
Please see the [instructions on how to install Foundation in a Rails app](http://foundation.zurb.com/docs/applications.html).
|
72
65
|
|
66
|
+
### Country Select
|
67
|
+
|
68
|
+
If you want to use the country select, you will need the
|
69
|
+
[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
gem 'country_select'
|
73
|
+
```
|
74
|
+
|
75
|
+
If you don't want to use the gem you can easily override this behaviour by mapping the
|
76
|
+
country inputs to something else, with a line like this in your `simple_form.rb` initializer:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
config.input_mappings = { /country/ => :string }
|
80
|
+
```
|
81
|
+
|
73
82
|
## Usage
|
74
83
|
|
75
84
|
**Simple Form** was designed to be customized as you need to. Basically it's a stack of components that
|
@@ -91,12 +100,12 @@ To start using **Simple Form** you just have to use the helper it provides:
|
|
91
100
|
This will generate an entire form with labels for user name and password as well, and render errors
|
92
101
|
by default when you render the form with invalid data (after submitting for example).
|
93
102
|
|
94
|
-
You can overwrite the default label by passing it to the input method. You can also add a hint
|
95
|
-
even a placeholder. For boolean inputs, you can add an inline label as well:
|
103
|
+
You can overwrite the default label by passing it to the input method. You can also add a hint,
|
104
|
+
an error, or even a placeholder. For boolean inputs, you can add an inline label as well:
|
96
105
|
|
97
106
|
```erb
|
98
107
|
<%= simple_form_for @user do |f| %>
|
99
|
-
<%= f.input :username, label: 'Your username please' %>
|
108
|
+
<%= f.input :username, label: 'Your username please', error: 'Username is mandatory, please specify one' %>
|
100
109
|
<%= f.input :password, hint: 'No special characters.' %>
|
101
110
|
<%= f.input :email, placeholder: 'user@domain.com' %>
|
102
111
|
<%= f.input :remember_me, inline_label: 'Yes, remember me' %>
|
@@ -259,7 +268,6 @@ end
|
|
259
268
|
```
|
260
269
|
|
261
270
|
For check boxes and radio buttons you can remove the label changing `boolean_style` from default value `:nested` to `:inline`.
|
262
|
-
Also, `item_wrapper_tag` will not work when `boolean_style` is set to `:nested`.
|
263
271
|
|
264
272
|
Example:
|
265
273
|
|
@@ -319,8 +327,9 @@ translation. All other options given are sent straight to the underlying helper.
|
|
319
327
|
can give prompt as:
|
320
328
|
|
321
329
|
```ruby
|
322
|
-
f.input :age, collection: 18..60, prompt: "Select your age"
|
330
|
+
f.input :age, collection: 18..60, prompt: "Select your age", selected: 21
|
323
331
|
```
|
332
|
+
Extra options are passed into helper [`collection_select`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select).
|
324
333
|
|
325
334
|
It is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:
|
326
335
|
|
@@ -404,7 +413,7 @@ The association helper just invokes `input` under the hood, so all options avail
|
|
404
413
|
the collection by hand, all together with the prompt:
|
405
414
|
|
406
415
|
```ruby
|
407
|
-
f.association :company, collection: Company.active.
|
416
|
+
f.association :company, collection: Company.active.order(:name), prompt: "Choose a Company"
|
408
417
|
```
|
409
418
|
|
410
419
|
In case you want to declare different labels and values:
|
@@ -435,6 +444,16 @@ The button method also accepts optional parameters, that are delegated to the un
|
|
435
444
|
<%= f.button :submit, "Custom Button Text", class: "my-button" %>
|
436
445
|
```
|
437
446
|
|
447
|
+
To create a `<button>` element, use the following syntax:
|
448
|
+
|
449
|
+
```erb
|
450
|
+
<%= f.button :button, "Custom Button Text" %>
|
451
|
+
|
452
|
+
<%= f.button :button do %>
|
453
|
+
Custom Button Text
|
454
|
+
<% end %>
|
455
|
+
```
|
456
|
+
|
438
457
|
### Wrapping Rails Form Helpers
|
439
458
|
|
440
459
|
Say you wanted to use a rails form helper but still wrap it in **Simple Form** goodness? You can, by
|
@@ -789,6 +808,22 @@ object itself. Thus, similarly, if a form for an `Admin::User` object is defined
|
|
789
808
|
`simple_form_for @admin_user, as: :some_user`, **Simple Form** will look for translations
|
790
809
|
under `some_user` instead of `admin_user`.
|
791
810
|
|
811
|
+
When translate `simple_fields_for` attributes be sure to use the same name you pass to it, e.g. `simple_fields_for :posts` should be placed under `posts` not `post`:
|
812
|
+
|
813
|
+
```yaml
|
814
|
+
en:
|
815
|
+
simple_form:
|
816
|
+
labels:
|
817
|
+
posts:
|
818
|
+
title: 'Post title'
|
819
|
+
hints:
|
820
|
+
posts:
|
821
|
+
title: 'A good title'
|
822
|
+
placeholders:
|
823
|
+
posts:
|
824
|
+
title: 'Once upon a time...'
|
825
|
+
```
|
826
|
+
|
792
827
|
## Configuration
|
793
828
|
|
794
829
|
**Simple Form** has several configuration options. You can read and change them in the initializer
|
@@ -1037,7 +1072,7 @@ https://github.com/plataformatec/simple_form/issues
|
|
1037
1072
|
|
1038
1073
|
## License
|
1039
1074
|
|
1040
|
-
MIT License. Copyright 2009-
|
1075
|
+
MIT License. Copyright 2009-2015 Plataformatec. http://plataformatec.com.br
|
1041
1076
|
|
1042
1077
|
You are not granted rights or licenses to the trademarks of the Plataformatec, including without
|
1043
1078
|
limitation the Simple Form name or logo.
|
@@ -90,8 +90,7 @@ SimpleForm.setup do |config|
|
|
90
90
|
# config.collection_wrapper_class = nil
|
91
91
|
|
92
92
|
# You can wrap each item in a collection of radio/check boxes with a tag,
|
93
|
-
# defaulting to :span.
|
94
|
-
# SimpleForm will force this option to be a label.
|
93
|
+
# defaulting to :span.
|
95
94
|
# config.item_wrapper_tag = :span
|
96
95
|
|
97
96
|
# You can define a class to use in all item wrappers. Defaulting to none.
|
@@ -87,7 +87,7 @@ SimpleForm.setup do |config|
|
|
87
87
|
|
88
88
|
b.wrapper tag: 'div', class: 'col-sm-offset-3 col-sm-9' do |wr|
|
89
89
|
wr.wrapper tag: 'div', class: 'checkbox' do |ba|
|
90
|
-
ba.use :label_input
|
90
|
+
ba.use :label_input
|
91
91
|
end
|
92
92
|
|
93
93
|
wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
@@ -122,6 +122,16 @@ SimpleForm.setup do |config|
|
|
122
122
|
b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
123
123
|
end
|
124
124
|
|
125
|
+
config.wrappers :multi_select, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
|
126
|
+
b.use :html5
|
127
|
+
b.optional :readonly
|
128
|
+
b.use :label, class: 'control-label'
|
129
|
+
b.wrapper tag: 'div', class: 'form-inline' do |ba|
|
130
|
+
ba.use :input, class: 'form-control'
|
131
|
+
ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
|
132
|
+
ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
|
133
|
+
end
|
134
|
+
end
|
125
135
|
# Wrappers for forms and inputs using the Bootstrap toolkit.
|
126
136
|
# Check the Bootstrap docs (http://getbootstrap.com)
|
127
137
|
# to learn about the different styles for forms and inputs,
|
@@ -132,5 +142,8 @@ SimpleForm.setup do |config|
|
|
132
142
|
radio_buttons: :vertical_radio_and_checkboxes,
|
133
143
|
file: :vertical_file_input,
|
134
144
|
boolean: :vertical_boolean,
|
145
|
+
datetime: :multi_select,
|
146
|
+
date: :multi_select,
|
147
|
+
time: :multi_select
|
135
148
|
}
|
136
149
|
end
|
@@ -7,10 +7,10 @@ module SimpleForm
|
|
7
7
|
|
8
8
|
def html5(wrapper_options = nil)
|
9
9
|
@html5 = true
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
|
11
|
+
input_html_options[:required] = has_required?
|
12
|
+
input_html_options[:'aria-required'] = has_required? || nil
|
13
|
+
|
14
14
|
nil
|
15
15
|
end
|
16
16
|
|
@@ -42,7 +42,7 @@ module SimpleForm
|
|
42
42
|
|
43
43
|
def label_html_options
|
44
44
|
label_html_classes = SimpleForm.additional_classes_for(:label) {
|
45
|
-
[input_type, required_class, SimpleForm.label_class].compact
|
45
|
+
[input_type, required_class, disabled_class, SimpleForm.label_class].compact
|
46
46
|
}
|
47
47
|
|
48
48
|
label_options = html_options_for(:label, label_html_classes)
|
@@ -30,6 +30,7 @@ module SimpleForm
|
|
30
30
|
map_type :date, :time, :datetime, to: SimpleForm::Inputs::DateTimeInput
|
31
31
|
map_type :country, :time_zone, to: SimpleForm::Inputs::PriorityInput
|
32
32
|
map_type :boolean, to: SimpleForm::Inputs::BooleanInput
|
33
|
+
map_type :hidden, to: SimpleForm::Inputs::HiddenInput
|
33
34
|
|
34
35
|
def self.discovery_cache
|
35
36
|
@discovery_cache ||= {}
|
@@ -206,8 +207,8 @@ module SimpleForm
|
|
206
207
|
options = args.extract_options!.dup
|
207
208
|
options[:class] = [SimpleForm.button_class, options[:class]].compact
|
208
209
|
args << options
|
209
|
-
if respond_to?("#{type}_button")
|
210
|
-
send("#{type}_button", *args, &block)
|
210
|
+
if respond_to?(:"#{type}_button")
|
211
|
+
send(:"#{type}_button", *args, &block)
|
211
212
|
else
|
212
213
|
send(type, *args, &block)
|
213
214
|
end
|
@@ -508,8 +509,8 @@ module SimpleForm
|
|
508
509
|
# collection is given.
|
509
510
|
def default_input_type(attribute_name, column, options)
|
510
511
|
return options[:as].to_sym if options[:as]
|
511
|
-
return :select if options[:collection]
|
512
512
|
custom_type = find_custom_type(attribute_name.to_s) and return custom_type
|
513
|
+
return :select if options[:collection]
|
513
514
|
|
514
515
|
input_type = column.try(:type)
|
515
516
|
case input_type
|
@@ -6,7 +6,7 @@ module SimpleForm
|
|
6
6
|
|
7
7
|
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
8
8
|
|
9
|
-
@builder.send("collection_#{input_type}",
|
9
|
+
@builder.send(:"collection_#{input_type}",
|
10
10
|
attribute_name, collection, value_method, label_method,
|
11
11
|
input_options, merged_input_options,
|
12
12
|
&collection_block_for_nested_boolean_style
|
@@ -14,16 +14,20 @@ module SimpleForm
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def label_target
|
17
|
-
|
18
|
-
|
19
|
-
date_order = input_options[:order] || I18n.t('date.order')
|
20
|
-
date_order.first.to_sym
|
17
|
+
if use_html5_inputs?
|
18
|
+
attribute_name
|
21
19
|
else
|
22
|
-
|
23
|
-
|
20
|
+
position = case input_type
|
21
|
+
when :date, :datetime
|
22
|
+
date_order = input_options[:order] || I18n.t('date.order')
|
23
|
+
date_order.first.to_sym
|
24
|
+
else
|
25
|
+
:hour
|
26
|
+
end
|
24
27
|
|
25
|
-
|
26
|
-
|
28
|
+
position = ActionView::Helpers::DateTimeSelector::POSITION[position]
|
29
|
+
"#{attribute_name}_#{position}i"
|
30
|
+
end
|
27
31
|
end
|
28
32
|
|
29
33
|
def use_html5_inputs?
|
data/lib/simple_form/version.rb
CHANGED
@@ -146,14 +146,14 @@ class ErrorTest < ActionView::TestCase
|
|
146
146
|
# FULL_ERROR_WRAPPER
|
147
147
|
|
148
148
|
test 'full error finds errors on association' do
|
149
|
-
swap_wrapper :default,
|
149
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
150
150
|
with_form_for @user, :company_id, as: :select
|
151
151
|
assert_select 'span.error', 'Company must be valid'
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
155
|
test 'full error finds errors on association with reflection' do
|
156
|
-
swap_wrapper :default,
|
156
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
157
157
|
with_form_for @user, :company_id, as: :select,
|
158
158
|
reflection: Association.new(Company, :company, {})
|
159
159
|
assert_select 'span.error', 'Company must be valid'
|
@@ -161,14 +161,14 @@ class ErrorTest < ActionView::TestCase
|
|
161
161
|
end
|
162
162
|
|
163
163
|
test 'full error can be disabled' do
|
164
|
-
swap_wrapper :default,
|
164
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
165
165
|
with_form_for @user, :company_id, as: :select, full_error: false
|
166
166
|
assert_no_select 'span.error'
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
170
170
|
test 'full error can be disabled setting error to false' do
|
171
|
-
swap_wrapper :default,
|
171
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
172
172
|
with_form_for @user, :company_id, as: :select, error: false
|
173
173
|
assert_no_select 'span.error'
|
174
174
|
end
|
@@ -196,7 +196,7 @@ class ErrorTest < ActionView::TestCase
|
|
196
196
|
end
|
197
197
|
|
198
198
|
test 'input with custom error works when using full_error component' do
|
199
|
-
swap_wrapper :default,
|
199
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
200
200
|
error_text = "Super User Name! cannot be blank"
|
201
201
|
with_form_for @user, :name, error: error_text
|
202
202
|
|
@@ -219,7 +219,7 @@ class ErrorTest < ActionView::TestCase
|
|
219
219
|
end
|
220
220
|
|
221
221
|
test 'input with custom error escapes the error text using full_error component' do
|
222
|
-
swap_wrapper :default,
|
222
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
223
223
|
with_form_for @user, :name, error: 'error must not contain <b>markup</b>'
|
224
224
|
|
225
225
|
assert_select 'span.error'
|
@@ -228,7 +228,7 @@ class ErrorTest < ActionView::TestCase
|
|
228
228
|
end
|
229
229
|
|
230
230
|
test 'input with custom error does not escape the error text if it is safe using full_error component' do
|
231
|
-
swap_wrapper :default,
|
231
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
232
232
|
with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe
|
233
233
|
|
234
234
|
assert_select 'span.error'
|
@@ -237,7 +237,7 @@ class ErrorTest < ActionView::TestCase
|
|
237
237
|
end
|
238
238
|
|
239
239
|
test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do
|
240
|
-
swap_wrapper :default,
|
240
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
241
241
|
with_form_for @user, :active, error: "Super User Active! can't be blank"
|
242
242
|
|
243
243
|
assert_no_select 'span.error'
|
@@ -46,6 +46,17 @@ class FormBuilderTest < ActionView::TestCase
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
test 'builder does not override custom input mappings for custom collection' do
|
50
|
+
swap SimpleForm, input_mappings: { /gender$/ => :check_boxes } do
|
51
|
+
with_concat_form_for @user do |f|
|
52
|
+
f.input :gender, collection: [:male, :female]
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_no_select 'select option', 'Male'
|
56
|
+
assert_select 'input[type=checkbox][value=male]'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
49
60
|
test 'builder allows to skip input_type class' do
|
50
61
|
swap SimpleForm, generate_additional_classes_for: [:label, :wrapper] do
|
51
62
|
with_form_for @user, :post_count
|
@@ -256,7 +267,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
256
267
|
end
|
257
268
|
|
258
269
|
test 'builder does not propagate input options to wrapper with custom wrapper' do
|
259
|
-
swap_wrapper :default,
|
270
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_input do
|
260
271
|
with_form_for @user, :name, input_html: { class: 'my_input' }
|
261
272
|
assert_no_select 'form div.input.my_input'
|
262
273
|
assert_select 'form input.my_input.string'
|
@@ -264,7 +275,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
264
275
|
end
|
265
276
|
|
266
277
|
test 'builder does not propagate label options to wrapper with custom wrapper' do
|
267
|
-
swap_wrapper :default,
|
278
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_label do
|
268
279
|
with_form_for @user, :name, label_html: { class: 'my_label' }
|
269
280
|
assert_no_select 'form div.label.my_label'
|
270
281
|
assert_select 'form label.my_label.string'
|
@@ -353,15 +364,15 @@ class FormBuilderTest < ActionView::TestCase
|
|
353
364
|
[:input, :input_field].each do |method|
|
354
365
|
test "builder receives a default argument and pass it to the inputs when calling '#{method}'" do
|
355
366
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
|
356
|
-
f.
|
367
|
+
f.public_send(method, :name)
|
357
368
|
end
|
358
369
|
assert_select 'input.default_class'
|
359
370
|
end
|
360
371
|
|
361
372
|
test "builder receives a default argument and pass it to the inputs without changing the defaults when calling '#{method}'" do
|
362
373
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|
|
363
|
-
concat(f.
|
364
|
-
concat(f.
|
374
|
+
concat(f.public_send(method, :name))
|
375
|
+
concat(f.public_send(method, :credit_limit))
|
365
376
|
end
|
366
377
|
|
367
378
|
assert_select "input.string.default_class[name='user[name]']"
|
@@ -372,9 +383,9 @@ class FormBuilderTest < ActionView::TestCase
|
|
372
383
|
@user.company = Company.new(1, 'Empresa')
|
373
384
|
|
374
385
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
|
375
|
-
concat(f.
|
386
|
+
concat(f.public_send(method, :name))
|
376
387
|
concat(f.simple_fields_for(:company) do |company_form|
|
377
|
-
concat(company_form.
|
388
|
+
concat(company_form.public_send(method, :name))
|
378
389
|
end)
|
379
390
|
end
|
380
391
|
|
@@ -2,10 +2,15 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
# Tests for f.input_field
|
4
4
|
class InputFieldTest < ActionView::TestCase
|
5
|
-
|
6
|
-
with_concat_form_for(
|
7
|
-
f.input_field
|
5
|
+
def with_input_field_for(object, *args)
|
6
|
+
with_concat_form_for(object) do |f|
|
7
|
+
f.input_field(*args)
|
8
8
|
end
|
9
|
+
end
|
10
|
+
|
11
|
+
test "builder input_field only renders the input tag, nothing else" do
|
12
|
+
with_input_field_for @user, :name
|
13
|
+
|
9
14
|
assert_select 'form > input.required.string'
|
10
15
|
assert_no_select 'div.string'
|
11
16
|
assert_no_select 'label'
|
@@ -13,45 +18,34 @@ class InputFieldTest < ActionView::TestCase
|
|
13
18
|
end
|
14
19
|
|
15
20
|
test 'builder input_field allows overriding default input type' do
|
16
|
-
|
17
|
-
f.input_field :name, as: :text
|
18
|
-
end
|
21
|
+
with_input_field_for @user, :name, as: :text
|
19
22
|
|
20
23
|
assert_no_select 'input#user_name'
|
21
24
|
assert_select 'textarea#user_name.text'
|
22
25
|
end
|
23
26
|
|
24
27
|
test 'builder input_field generates input type based on column type' do
|
25
|
-
|
26
|
-
f.input_field :age
|
27
|
-
end
|
28
|
+
with_input_field_for @user, :age
|
28
29
|
|
29
30
|
assert_select 'input[type=number].integer#user_age'
|
30
31
|
end
|
31
32
|
|
32
33
|
test 'builder input_field is able to disable any component' do
|
33
|
-
|
34
|
-
f.input_field :age, html5: false
|
35
|
-
end
|
34
|
+
with_input_field_for @user, :age, html5: false
|
36
35
|
|
37
36
|
assert_no_select 'input[html5=false]#user_age'
|
38
37
|
assert_select 'input[type=text].integer#user_age'
|
39
38
|
end
|
40
39
|
|
41
40
|
test 'builder input_field allows passing options to input tag' do
|
42
|
-
|
43
|
-
f.input_field :name, id: 'name_input', class: 'name'
|
44
|
-
end
|
41
|
+
with_input_field_for @user, :name, id: 'name_input', class: 'name'
|
45
42
|
|
46
43
|
assert_select 'input.string.name#name_input'
|
47
44
|
end
|
48
45
|
|
49
46
|
test 'builder input_field does not modify the options hash' do
|
50
47
|
options = { id: 'name_input', class: 'name' }
|
51
|
-
|
52
|
-
with_concat_form_for(@user) do |f|
|
53
|
-
f.input_field :name, options
|
54
|
-
end
|
48
|
+
with_input_field_for @user, :name, options
|
55
49
|
|
56
50
|
assert_select 'input.string.name#name_input'
|
57
51
|
assert_equal({ id: 'name_input', class: 'name' }, options)
|
@@ -59,9 +53,7 @@ class InputFieldTest < ActionView::TestCase
|
|
59
53
|
|
60
54
|
|
61
55
|
test 'builder input_field generates an input tag with a clean HTML' do
|
62
|
-
|
63
|
-
f.input_field :name, as: :integer, class: 'name'
|
64
|
-
end
|
56
|
+
with_input_field_for @user, :name, as: :integer, class: 'name'
|
65
57
|
|
66
58
|
assert_no_select 'input.integer[input_html]'
|
67
59
|
assert_no_select 'input.integer[as]'
|
@@ -71,67 +63,51 @@ class InputFieldTest < ActionView::TestCase
|
|
71
63
|
store_translations(:en, simple_form: { placeholders: { user: {
|
72
64
|
name: 'Name goes here'
|
73
65
|
} } }) do
|
74
|
-
|
75
|
-
with_concat_form_for(@user) do |f|
|
76
|
-
f.input_field :name
|
77
|
-
end
|
66
|
+
with_input_field_for @user, :name
|
78
67
|
|
79
68
|
assert_select 'input.string[placeholder="Name goes here"]'
|
80
69
|
end
|
81
70
|
end
|
82
71
|
|
83
72
|
test 'builder input_field uses min_max component' do
|
84
|
-
|
85
|
-
f.input_field :age, as: :integer
|
86
|
-
end
|
73
|
+
with_input_field_for @other_validating_user, :age, as: :integer
|
87
74
|
|
88
75
|
assert_select 'input[min="18"]'
|
89
76
|
end
|
90
77
|
|
91
78
|
test 'builder input_field does not use pattern component by default' do
|
92
|
-
|
93
|
-
f.input_field :country, as: :string
|
94
|
-
end
|
79
|
+
with_input_field_for @other_validating_user, :country, as: :string
|
95
80
|
|
96
81
|
assert_no_select 'input[pattern="\w+"]'
|
97
82
|
end
|
98
83
|
|
99
84
|
test 'builder input_field infers pattern from attributes' do
|
100
|
-
|
101
|
-
f.input_field :country, as: :string, pattern: true
|
102
|
-
end
|
85
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: true
|
103
86
|
|
104
87
|
assert_select 'input[pattern="\w+"]'
|
105
88
|
end
|
106
89
|
|
107
90
|
test 'builder input_field accepts custom patter' do
|
108
|
-
|
109
|
-
f.input_field :country, as: :string, pattern: '\d+'
|
110
|
-
end
|
91
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: '\d+'
|
111
92
|
|
112
93
|
assert_select 'input[pattern="\d+"]'
|
113
94
|
end
|
114
95
|
|
115
96
|
test 'builder input_field uses readonly component' do
|
116
|
-
|
117
|
-
f.input_field :age, as: :integer, readonly: true
|
118
|
-
end
|
97
|
+
with_input_field_for @other_validating_user, :age, as: :integer, readonly: true
|
119
98
|
|
120
99
|
assert_select 'input.integer.readonly[readonly]'
|
121
100
|
end
|
122
101
|
|
123
102
|
test 'builder input_field uses maxlength component' do
|
124
|
-
|
125
|
-
f.input_field :name, as: :string
|
126
|
-
end
|
103
|
+
with_input_field_for @validating_user, :name, as: :string
|
127
104
|
|
128
105
|
assert_select 'input.string[maxlength="25"]'
|
129
106
|
end
|
130
107
|
|
131
108
|
test 'builder collection input_field generates input tag with a clean HTML' do
|
132
|
-
|
133
|
-
|
134
|
-
end
|
109
|
+
with_input_field_for @user, :status, collection: ['Open', 'Closed'],
|
110
|
+
class: 'status', label_method: :to_s, value_method: :to_s
|
135
111
|
|
136
112
|
assert_no_select 'select.status[input_html]'
|
137
113
|
assert_no_select 'select.status[collection]'
|
@@ -140,48 +116,38 @@ class InputFieldTest < ActionView::TestCase
|
|
140
116
|
end
|
141
117
|
|
142
118
|
test 'build input_field does not treat "boolean_style" as a HTML attribute' do
|
143
|
-
|
144
|
-
f.input_field :active, boolean_style: :nested
|
145
|
-
end
|
119
|
+
with_input_field_for @user, :active, boolean_style: :nested
|
146
120
|
|
147
121
|
assert_no_select 'input.boolean[boolean_style]'
|
148
122
|
end
|
149
123
|
|
150
124
|
test 'build input_field without pattern component use the pattern string' do
|
151
|
-
swap_wrapper :default,
|
152
|
-
|
153
|
-
f.input_field :name, pattern: '\w+'
|
154
|
-
end
|
125
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
126
|
+
with_input_field_for @user, :name, pattern: '\w+'
|
155
127
|
|
156
128
|
assert_select 'input[pattern="\w+"]'
|
157
129
|
end
|
158
130
|
end
|
159
131
|
|
160
132
|
test 'build input_field without placeholder component use the placeholder string' do
|
161
|
-
swap_wrapper :default,
|
162
|
-
|
163
|
-
f.input_field :name, placeholder: 'Placeholder'
|
164
|
-
end
|
133
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
134
|
+
with_input_field_for @user, :name, placeholder: 'Placeholder'
|
165
135
|
|
166
136
|
assert_select 'input[placeholder="Placeholder"]'
|
167
137
|
end
|
168
138
|
end
|
169
139
|
|
170
140
|
test 'build input_field without maxlength component use the maxlength string' do
|
171
|
-
swap_wrapper :default,
|
172
|
-
|
173
|
-
f.input_field :name, maxlength: 5
|
174
|
-
end
|
141
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
142
|
+
with_input_field_for @user, :name, maxlength: 5
|
175
143
|
|
176
144
|
assert_select 'input[maxlength="5"]'
|
177
145
|
end
|
178
146
|
end
|
179
147
|
|
180
148
|
test 'build input_field without readonly component use the readonly string' do
|
181
|
-
swap_wrapper :default,
|
182
|
-
|
183
|
-
f.input_field :name, readonly: true
|
184
|
-
end
|
149
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
150
|
+
with_input_field_for @user, :name, readonly: true
|
185
151
|
|
186
152
|
assert_select 'input[readonly="readonly"]'
|
187
153
|
end
|
@@ -29,6 +29,16 @@ class LabelTest < ActionView::TestCase
|
|
29
29
|
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
30
30
|
end
|
31
31
|
|
32
|
+
test 'builder adds a disabled class to label if the attribute is disabled' do
|
33
|
+
with_label_for @validating_user, :name, disabled: true
|
34
|
+
assert_select 'label.string.disabled[for=validating_user_name]', /Name/
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'builder does not add a disabled class to label if the attribute is not disabled' do
|
38
|
+
with_label_for @validating_user, :name, disabled: false
|
39
|
+
assert_no_select 'label.string.disabled[for=validating_user_name]', /Name/
|
40
|
+
end
|
41
|
+
|
32
42
|
test 'builder escapes label text' do
|
33
43
|
with_label_for @user, :name, label: '<script>alert(1337)</script>', required: false
|
34
44
|
assert_no_select 'label.string script'
|
@@ -80,7 +90,7 @@ class LabelTest < ActionView::TestCase
|
|
80
90
|
end
|
81
91
|
|
82
92
|
test 'configuration allow set label text for wrappers' do
|
83
|
-
swap_wrapper :default,
|
93
|
+
swap_wrapper :default, custom_wrapper_with_label_text do
|
84
94
|
with_concat_form_for(@user) do |f|
|
85
95
|
concat f.input :age
|
86
96
|
end
|
@@ -89,7 +99,7 @@ class LabelTest < ActionView::TestCase
|
|
89
99
|
end
|
90
100
|
|
91
101
|
test 'configuration allow set rewrited label tag for wrappers' do
|
92
|
-
swap_wrapper :default,
|
102
|
+
swap_wrapper :default, custom_wrapper_with_custom_label_component do
|
93
103
|
with_concat_form_for(@user) do |f|
|
94
104
|
concat f.input :age
|
95
105
|
end
|
@@ -129,7 +129,7 @@ class WrapperTest < ActionView::TestCase
|
|
129
129
|
end
|
130
130
|
|
131
131
|
test 'custom wrappers can have additional attributes' do
|
132
|
-
swap_wrapper :default,
|
132
|
+
swap_wrapper :default, custom_wrapper_with_additional_attributes do
|
133
133
|
with_form_for @user, :name
|
134
134
|
|
135
135
|
assert_select "div.custom_wrapper[title='some title'][data-wrapper='test']"
|
@@ -137,7 +137,7 @@ class WrapperTest < ActionView::TestCase
|
|
137
137
|
end
|
138
138
|
|
139
139
|
test 'custom wrappers can have full error message on attributes' do
|
140
|
-
swap_wrapper :default,
|
140
|
+
swap_wrapper :default, custom_wrapper_with_full_error do
|
141
141
|
with_form_for @user, :name
|
142
142
|
assert_select 'span.error', "Name cannot be blank"
|
143
143
|
end
|
@@ -188,7 +188,7 @@ class WrapperTest < ActionView::TestCase
|
|
188
188
|
end
|
189
189
|
|
190
190
|
test 'does not duplicate label classes for different inputs' do
|
191
|
-
swap_wrapper :default,
|
191
|
+
swap_wrapper :default, custom_wrapper_with_label_html_option do
|
192
192
|
with_concat_form_for(@user) do |f|
|
193
193
|
concat f.input :name, required: false
|
194
194
|
concat f.input :email, as: :email, required: true
|
@@ -243,7 +243,7 @@ class WrapperTest < ActionView::TestCase
|
|
243
243
|
end
|
244
244
|
|
245
245
|
test 'input accepts attributes in the DSL' do
|
246
|
-
swap_wrapper :default,
|
246
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
247
247
|
with_concat_form_for @user do |f|
|
248
248
|
concat f.input :name
|
249
249
|
end
|
@@ -253,7 +253,7 @@ class WrapperTest < ActionView::TestCase
|
|
253
253
|
end
|
254
254
|
|
255
255
|
test 'label accepts attributes in the DSL' do
|
256
|
-
swap_wrapper :default,
|
256
|
+
swap_wrapper :default, custom_wrapper_with_label_class do
|
257
257
|
with_concat_form_for @user do |f|
|
258
258
|
concat f.input :name
|
259
259
|
end
|
@@ -263,7 +263,7 @@ class WrapperTest < ActionView::TestCase
|
|
263
263
|
end
|
264
264
|
|
265
265
|
test 'label_input accepts attributes in the DSL' do
|
266
|
-
swap_wrapper :default,
|
266
|
+
swap_wrapper :default, custom_wrapper_with_label_input_class do
|
267
267
|
with_concat_form_for @user do |f|
|
268
268
|
concat f.input :name
|
269
269
|
end
|
@@ -274,7 +274,7 @@ class WrapperTest < ActionView::TestCase
|
|
274
274
|
end
|
275
275
|
|
276
276
|
test 'input accepts data attributes in the DSL' do
|
277
|
-
swap_wrapper :default,
|
277
|
+
swap_wrapper :default, custom_wrapper_with_input_attributes do
|
278
278
|
with_concat_form_for @user do |f|
|
279
279
|
concat f.input :name
|
280
280
|
end
|
@@ -284,7 +284,7 @@ class WrapperTest < ActionView::TestCase
|
|
284
284
|
end
|
285
285
|
|
286
286
|
test 'inline wrapper displays when there is content' do
|
287
|
-
swap_wrapper :default,
|
287
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
288
288
|
with_form_for @user, :name, hint: "cannot be blank"
|
289
289
|
assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', "cannot be blank"
|
290
290
|
assert_select 'p.omg_hint'
|
@@ -292,7 +292,7 @@ class WrapperTest < ActionView::TestCase
|
|
292
292
|
end
|
293
293
|
|
294
294
|
test 'inline wrapper does not display when there is no content' do
|
295
|
-
swap_wrapper :default,
|
295
|
+
swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do
|
296
296
|
with_form_for @user, :name
|
297
297
|
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
298
298
|
assert_no_select 'p.omg_hint'
|
@@ -300,7 +300,7 @@ class WrapperTest < ActionView::TestCase
|
|
300
300
|
end
|
301
301
|
|
302
302
|
test 'optional wrapper does not display when there is content' do
|
303
|
-
swap_wrapper :default,
|
303
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
304
304
|
with_form_for @user, :name, hint: "can't be blank"
|
305
305
|
assert_select 'section.custom_wrapper div.no_output_wrapper'
|
306
306
|
assert_select 'div.no_output_wrapper'
|
@@ -309,7 +309,7 @@ class WrapperTest < ActionView::TestCase
|
|
309
309
|
end
|
310
310
|
|
311
311
|
test 'optional wrapper does not display when there is no content' do
|
312
|
-
swap_wrapper :default,
|
312
|
+
swap_wrapper :default, custom_wrapper_with_unless_blank do
|
313
313
|
with_form_for @user, :name
|
314
314
|
assert_no_select 'section.custom_wrapper div.no_output_wrapper'
|
315
315
|
assert_no_select 'div.no_output_wrapper'
|
@@ -169,4 +169,9 @@ class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
|
169
169
|
with_input_for :project, :created_at, :time, html5: false
|
170
170
|
assert_select 'label[for=project_created_at_4i]'
|
171
171
|
end
|
172
|
+
|
173
|
+
test 'label points to attribute name if HTML5 compatibility is explicitly enabled' do
|
174
|
+
with_input_for :project, :created_at, :date, html5: true
|
175
|
+
assert_select 'label[for=project_created_at]'
|
176
|
+
end
|
172
177
|
end
|
@@ -110,4 +110,16 @@ class RequiredTest < ActionView::TestCase
|
|
110
110
|
assert_no_select 'input[required]'
|
111
111
|
assert_select 'input.optional#validating_user_phone_number'
|
112
112
|
end
|
113
|
+
|
114
|
+
test 'builder input does not generate required html attribute when option is set to false when it is set to true in wrapper' do
|
115
|
+
swap SimpleForm, browser_validations: true do
|
116
|
+
swap_wrapper :default, self.custom_wrapper_with_required_input do
|
117
|
+
with_concat_form_for(@user) do |f|
|
118
|
+
concat f.input :name, required: false
|
119
|
+
end
|
120
|
+
assert_no_select 'input[type=text][required]'
|
121
|
+
assert_no_select 'input[type=text][aria-required]'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
113
125
|
end
|
@@ -12,6 +12,13 @@ class TextInputTest < ActionView::TestCase
|
|
12
12
|
assert_select 'textarea.text[placeholder="Put in some text"]'
|
13
13
|
end
|
14
14
|
|
15
|
+
test 'input generates a placeholder from the translations' do
|
16
|
+
store_translations(:en, simple_form: { placeholders: { user: { name: "placeholder from i18n en.simple_form.placeholders.user.name" } } }) do
|
17
|
+
with_input_for @user, :name, :text
|
18
|
+
assert_select 'textarea.text[placeholder="placeholder from i18n en.simple_form.placeholders.user.name"]'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
15
22
|
test 'input gets maxlength from column definition for text attributes' do
|
16
23
|
with_input_for @user, :description, :text
|
17
24
|
assert_select 'textarea.text[maxlength="200"]'
|
@@ -46,7 +46,7 @@ module MiscHelpers
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def swap_wrapper(name = :default, wrapper =
|
49
|
+
def swap_wrapper(name = :default, wrapper = custom_wrapper)
|
50
50
|
old = SimpleForm.wrappers[name.to_s]
|
51
51
|
SimpleForm.wrappers[name.to_s] = wrapper
|
52
52
|
yield
|
@@ -184,6 +184,13 @@ module MiscHelpers
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
+
def custom_wrapper_with_required_input
|
188
|
+
SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
|
189
|
+
b.use :html5
|
190
|
+
b.use :input, required: true
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
187
194
|
def custom_form_for(object, *args, &block)
|
188
195
|
simple_form_for(object, *args, { builder: CustomFormBuilder }, &block)
|
189
196
|
end
|
data/test/test_helper.rb
CHANGED
@@ -36,6 +36,10 @@ else
|
|
36
36
|
ActionDispatch::Assertions::NO_STRIP << "label"
|
37
37
|
end
|
38
38
|
|
39
|
+
if ActiveSupport::TestCase.respond_to?(:test_order=)
|
40
|
+
ActiveSupport::TestCase.test_order = :random
|
41
|
+
end
|
42
|
+
|
39
43
|
class ActionView::TestCase
|
40
44
|
include MiscHelpers
|
41
45
|
include SimpleForm::ActionViewExtensions::FormHelper
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- José Valim
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-08-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activemodel
|
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
166
|
version: '0'
|
167
167
|
requirements: []
|
168
168
|
rubyforge_project: simple_form
|
169
|
-
rubygems_version: 2.
|
169
|
+
rubygems_version: 2.4.5
|
170
170
|
signing_key:
|
171
171
|
specification_version: 4
|
172
172
|
summary: Forms made easy!
|