simple_form 3.2.1 → 3.3.0
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 +15 -1
- data/MIT-LICENSE +1 -1
- data/README.md +19 -15
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +0 -0
- data/lib/simple_form.rb +0 -4
- data/lib/simple_form/action_view_extensions/form_helper.rb +3 -1
- data/lib/simple_form/components/html5.rb +12 -2
- data/lib/simple_form/components/maxlength.rb +17 -4
- data/lib/simple_form/form_builder.rb +12 -5
- data/lib/simple_form/inputs/base.rb +9 -4
- data/lib/simple_form/inputs/boolean_input.rb +5 -0
- data/lib/simple_form/version.rb +1 -1
- data/test/form_builder/error_test.rb +24 -1
- data/test/form_builder/general_test.rb +5 -1
- data/test/form_builder/input_field_test.rb +6 -0
- data/test/form_builder/label_test.rb +7 -0
- data/test/form_builder/wrapper_test.rb +32 -0
- data/test/inputs/boolean_input_test.rb +8 -0
- data/test/inputs/datetime_input_test.rb +10 -2
- data/test/inputs/discovery_test.rb +1 -0
- data/test/inputs/numeric_input_test.rb +3 -0
- data/test/inputs/priority_input_test.rb +10 -2
- data/test/inputs/required_test.rb +32 -0
- data/test/inputs/string_input_test.rb +5 -3
- data/test/support/misc_helpers.rb +14 -0
- data/test/support/models.rb +30 -5
- 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: c12e271b03625f2cca73aaf99d1229e212d549b5
|
4
|
+
data.tar.gz: baa9c72a065dda6000b52852edaafc5f60e38a30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 625bb4d60627789d65f73dcc2d5aafc7159cb9b66c12a911b6e0ef832075cf3b330d2636b97aa17f8f93037ef2d917b03cf2926ead2b6091a389fd6e3ed22b43
|
7
|
+
data.tar.gz: 139633282c1518a82841c62cedf6451a983a5058ed6d865f6a295874dac8e9156932b95490e4d3dada97d85c685c9c687a7a25bb926bcd75f3aef00252e33f4b
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## 3.3.0
|
4
|
+
|
5
|
+
### enhancements
|
6
|
+
* Add the `aria-invalid` attribute on inputs with errors.
|
7
|
+
* Added support for the new `ActiveModel::Type` API over Active Record's
|
8
|
+
column objects.
|
9
|
+
|
10
|
+
### bug fix
|
11
|
+
* Fix `merge_wrapper_options` to correctly merge options with duplicated keys. [@herminiotorres](https://github.com/herminiotorres)
|
12
|
+
Closes [#1278](https://github.com/plataformatec/simple_form/issues/1278).
|
13
|
+
|
1
14
|
## 3.2.1
|
2
15
|
|
3
|
-
|
16
|
+
### enhancements
|
17
|
+
* Updated gem dependency to support Rails 5.0.x.
|
4
18
|
|
5
19
|
## 3.2.0
|
6
20
|
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2009-
|
1
|
+
Copyright (c) 2009-2016 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
@@ -164,8 +164,9 @@ any html attribute to that wrapper as well using the `:wrapper_html` option, lik
|
|
164
164
|
|
165
165
|
Required fields are marked with an * prepended to their labels.
|
166
166
|
|
167
|
-
By default all inputs are required. When the form object
|
168
|
-
|
167
|
+
By default all inputs are required. When the form object includes `ActiveModel::Validations`
|
168
|
+
(which, for example, happens with Active Record models), fields are required only when there is `presence` validation.
|
169
|
+
Otherwise, **Simple Form** will mark fields as optional. For performance reasons, this
|
169
170
|
detection is skipped on validations that make use of conditional options, such as `:if` and `:unless`.
|
170
171
|
|
171
172
|
And of course, the `required` property of any input can be overwritten as needed:
|
@@ -323,14 +324,17 @@ Collection inputs accept two other options beside collections:
|
|
323
324
|
|
324
325
|
Those methods are useful to manipulate the given collection. Both of these options also accept
|
325
326
|
lambda/procs in case you want to calculate the value or label in a special way eg. custom
|
326
|
-
translation.
|
327
|
-
|
327
|
+
translation. You can also define a `to_label` method on your model as **Simple Form** will search for
|
328
|
+
and use `:to_label` as a `:label_method` first if it is found. All other options given are sent
|
329
|
+
straight to the underlying helper. For example, you can give prompt as:
|
328
330
|
|
329
331
|
```ruby
|
330
332
|
f.input :age, collection: 18..60, prompt: "Select your age", selected: 21
|
331
333
|
```
|
332
334
|
Extra options are passed into helper [`collection_select`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select).
|
333
335
|
|
336
|
+
You may also find it useful to explicitly pass a value to the optional `:selected`, especially if passing a collection of nested objects.
|
337
|
+
|
334
338
|
It is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:
|
335
339
|
|
336
340
|
```ruby
|
@@ -679,7 +683,7 @@ en:
|
|
679
683
|
age: 'Rather not say'
|
680
684
|
prompts:
|
681
685
|
user:
|
682
|
-
|
686
|
+
role: 'Select your role'
|
683
687
|
```
|
684
688
|
|
685
689
|
And your forms will use this information to render the components for you.
|
@@ -734,16 +738,16 @@ For `:prompt` and `:include_blank` the I18n lookup is optional and to enable it
|
|
734
738
|
`:translate` as value.
|
735
739
|
|
736
740
|
```ruby
|
737
|
-
f.input :
|
741
|
+
f.input :role, prompt: :translate
|
738
742
|
```
|
739
743
|
|
740
744
|
**Simple Form** also has support for translating options in collection helpers. For instance, given a
|
741
|
-
User with a `:
|
742
|
-
that would post either `
|
745
|
+
User with a `:role` attribute, you might want to create a select box showing translated labels
|
746
|
+
that would post either `:admin` or `:editor` as value. With **Simple Form** you could create an input
|
743
747
|
like this:
|
744
748
|
|
745
749
|
```ruby
|
746
|
-
f.input :
|
750
|
+
f.input :role, collection: [:admin, :editor]
|
747
751
|
```
|
748
752
|
|
749
753
|
And **Simple Form** will try a lookup like this in your locale file, to find the right labels to show:
|
@@ -753,9 +757,9 @@ en:
|
|
753
757
|
simple_form:
|
754
758
|
options:
|
755
759
|
user:
|
756
|
-
|
757
|
-
|
758
|
-
|
760
|
+
role:
|
761
|
+
admin: 'Administrator'
|
762
|
+
editor: 'Editor'
|
759
763
|
```
|
760
764
|
|
761
765
|
You can also use the `defaults` key as you would do with labels, hints and placeholders. It is
|
@@ -982,8 +986,8 @@ required attribute to force a value into an input and will prevent form submissi
|
|
982
986
|
Depending on the design of the application this may or may not be desired. In many cases it can
|
983
987
|
break existing UI's.
|
984
988
|
|
985
|
-
It is possible to disable all HTML 5 extensions in **Simple Form** removing the `html5`
|
986
|
-
from the wrapper used to render the inputs.
|
989
|
+
It is possible to disable all HTML 5 extensions in **Simple Form** by removing the `html5`
|
990
|
+
component from the wrapper used to render the inputs.
|
987
991
|
|
988
992
|
For example, change:
|
989
993
|
|
@@ -1072,7 +1076,7 @@ https://github.com/plataformatec/simple_form/issues
|
|
1072
1076
|
|
1073
1077
|
## License
|
1074
1078
|
|
1075
|
-
MIT License. Copyright 2009-
|
1079
|
+
MIT License. Copyright 2009-2016 Plataformatec. http://plataformatec.com.br
|
1076
1080
|
|
1077
1081
|
You are not granted rights or licenses to the trademarks of the Plataformatec, including without
|
1078
1082
|
limitation the Simple Form name or logo.
|
File without changes
|
data/lib/simple_form.rb
CHANGED
@@ -152,10 +152,6 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
152
152
|
mattr_accessor :country_priority
|
153
153
|
@@country_priority = nil
|
154
154
|
|
155
|
-
# DEPRECATED: Maximum size allowed for inputs.
|
156
|
-
mattr_accessor :default_input_size
|
157
|
-
@@default_input_size = nil
|
158
|
-
|
159
155
|
# When off, do not use translations in labels. Disabling translation in
|
160
156
|
# hints and placeholders can be done manually in the wrapper API.
|
161
157
|
mattr_accessor :translate_labels
|
@@ -8,8 +8,10 @@ module SimpleForm
|
|
8
8
|
def html5(wrapper_options = nil)
|
9
9
|
@html5 = true
|
10
10
|
|
11
|
-
input_html_options[:required] =
|
12
|
-
input_html_options[:'aria-required'] =
|
11
|
+
input_html_options[:required] = input_html_required_option
|
12
|
+
input_html_options[:'aria-required'] = input_html_aria_required_option
|
13
|
+
|
14
|
+
input_html_options[:'aria-invalid'] = has_errors? || nil
|
13
15
|
|
14
16
|
nil
|
15
17
|
end
|
@@ -18,6 +20,14 @@ module SimpleForm
|
|
18
20
|
@html5
|
19
21
|
end
|
20
22
|
|
23
|
+
def input_html_required_option
|
24
|
+
!options[:required].nil? ? required_field? : has_required?
|
25
|
+
end
|
26
|
+
|
27
|
+
def input_html_aria_required_option
|
28
|
+
!options[:required].nil? ? (required_field? || nil) : (has_required? || nil)
|
29
|
+
end
|
30
|
+
|
21
31
|
def has_required?
|
22
32
|
# We need to check browser_validations because
|
23
33
|
# some browsers are still checking required even
|
@@ -15,10 +15,7 @@ module SimpleForm
|
|
15
15
|
maxlength
|
16
16
|
else
|
17
17
|
length_validator = find_length_validator
|
18
|
-
|
19
|
-
if length_validator && !has_tokenizer?(length_validator)
|
20
|
-
length_validator.options[:is] || length_validator.options[:maximum]
|
21
|
-
end
|
18
|
+
maximum_length_value_from(length_validator)
|
22
19
|
end
|
23
20
|
end
|
24
21
|
|
@@ -29,6 +26,22 @@ module SimpleForm
|
|
29
26
|
def has_tokenizer?(length_validator)
|
30
27
|
length_validator.options[:tokenizer]
|
31
28
|
end
|
29
|
+
|
30
|
+
# Use validation with tokenizer if version of Rails is less than 5,
|
31
|
+
# if not validate without the tokenizer, if version is greater than Rails 4.
|
32
|
+
if ActionPack::VERSION::STRING < '5'
|
33
|
+
def maximum_length_value_from(length_validator)
|
34
|
+
if length_validator && !has_tokenizer?(length_validator)
|
35
|
+
length_validator.options[:is] || length_validator.options[:maximum]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
elsif ActionPack::VERSION::STRING >= '5'
|
39
|
+
def maximum_length_value_from(length_validator)
|
40
|
+
if length_validator
|
41
|
+
length_validator.options[:is] || length_validator.options[:maximum]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
32
45
|
end
|
33
46
|
end
|
34
47
|
end
|
@@ -48,6 +48,11 @@ module SimpleForm
|
|
48
48
|
# label + input + hint (when defined) + errors (when exists), and all can
|
49
49
|
# be configured inside a wrapper html.
|
50
50
|
#
|
51
|
+
# If a block is given, the contents of the block will replace the input
|
52
|
+
# field that would otherwise be generated automatically. The content will
|
53
|
+
# be given a label and wrapper div to make it consistent with the other
|
54
|
+
# elements in the form.
|
55
|
+
#
|
51
56
|
# == Examples
|
52
57
|
#
|
53
58
|
# # Imagine @user has error "can't be blank" on name
|
@@ -135,7 +140,7 @@ module SimpleForm
|
|
135
140
|
components = (wrapper.components.map(&:namespace) & ATTRIBUTE_COMPONENTS)
|
136
141
|
|
137
142
|
options = options.dup
|
138
|
-
options[:input_html] = options.except(:as, :boolean_style, :collection, :label_method, :value_method, *components)
|
143
|
+
options[:input_html] = options.except(:as, :boolean_style, :collection, :label_method, :value_method, :prompt, *components)
|
139
144
|
options = @defaults.deep_dup.deep_merge(options) if @defaults
|
140
145
|
|
141
146
|
input = find_input(attribute_name, options)
|
@@ -285,7 +290,7 @@ module SimpleForm
|
|
285
290
|
#
|
286
291
|
# f.label :name # Do I18n lookup
|
287
292
|
# f.label :name, "Name" # Same behavior as Rails, do not add required tag
|
288
|
-
# f.label :name, label: "Name"
|
293
|
+
# f.label :name, label: "Name" # Same as above, but adds required tag
|
289
294
|
#
|
290
295
|
# f.label :name, required: false
|
291
296
|
# f.label :name, id: "cool_label"
|
@@ -294,7 +299,7 @@ module SimpleForm
|
|
294
299
|
return super if args.first.is_a?(String) || block_given?
|
295
300
|
|
296
301
|
options = args.extract_options!.dup
|
297
|
-
options[:label_html] = options.except(:label, :required, :as)
|
302
|
+
options[:label_html] = options.except(:label, :label_text, :required, :as)
|
298
303
|
|
299
304
|
column = find_attribute_column(attribute_name)
|
300
305
|
input_type = default_input_type(attribute_name, column, options)
|
@@ -505,7 +510,7 @@ module SimpleForm
|
|
505
510
|
end
|
506
511
|
|
507
512
|
# Attempt to guess the better input type given the defined options. By
|
508
|
-
# default
|
513
|
+
# default always fallback to the user :as option, or to a :select when a
|
509
514
|
# collection is given.
|
510
515
|
def default_input_type(attribute_name, column, options)
|
511
516
|
return options[:as].to_sym if options[:as]
|
@@ -544,7 +549,9 @@ module SimpleForm
|
|
544
549
|
end
|
545
550
|
|
546
551
|
def find_attribute_column(attribute_name)
|
547
|
-
if @object.respond_to?(:
|
552
|
+
if @object.respond_to?(:type_for_attribute) && @object.has_attribute?(attribute_name)
|
553
|
+
@object.type_for_attribute(attribute_name)
|
554
|
+
elsif @object.respond_to?(:column_for_attribute) && @object.has_attribute?(attribute_name)
|
548
555
|
@object.column_for_attribute(attribute_name)
|
549
556
|
end
|
550
557
|
end
|
@@ -115,7 +115,7 @@ module SimpleForm
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def decimal_or_float?
|
118
|
-
column.
|
118
|
+
column.type == :float || column.type == :decimal
|
119
119
|
end
|
120
120
|
|
121
121
|
def nested_boolean_style?
|
@@ -189,9 +189,14 @@ module SimpleForm
|
|
189
189
|
|
190
190
|
def merge_wrapper_options(options, wrapper_options)
|
191
191
|
if wrapper_options
|
192
|
-
|
193
|
-
|
194
|
-
|
192
|
+
wrapper_options.merge(options) do |key, oldval, newval|
|
193
|
+
case key.to_s
|
194
|
+
when "class"
|
195
|
+
Array(oldval) + Array(newval)
|
196
|
+
when "data", "aria"
|
197
|
+
oldval.merge(newval)
|
198
|
+
else
|
199
|
+
newval
|
195
200
|
end
|
196
201
|
end
|
197
202
|
else
|
@@ -55,6 +55,7 @@ module SimpleForm
|
|
55
55
|
# we need the hidden field to be *outside* the label (otherwise it
|
56
56
|
# generates invalid html - html5 only).
|
57
57
|
def build_hidden_field_for_checkbox
|
58
|
+
return "" unless include_hidden?
|
58
59
|
options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
|
59
60
|
options[:name] = input_html_options[:name] if input_html_options.has_key?(:name)
|
60
61
|
|
@@ -81,6 +82,10 @@ module SimpleForm
|
|
81
82
|
false
|
82
83
|
end
|
83
84
|
|
85
|
+
def include_hidden?
|
86
|
+
options.fetch(:include_hidden, true)
|
87
|
+
end
|
88
|
+
|
84
89
|
def checked_value
|
85
90
|
options.fetch(:checked_value, '1')
|
86
91
|
end
|
data/lib/simple_form/version.rb
CHANGED
@@ -94,13 +94,36 @@ class ErrorTest < ActionView::TestCase
|
|
94
94
|
assert_no_select 'span.error b', 'markup'
|
95
95
|
end
|
96
96
|
|
97
|
-
|
98
97
|
test 'error generates an error message with raw HTML tags' do
|
99
98
|
with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
|
100
99
|
assert_select 'span.error', "Name cannot be blank"
|
101
100
|
assert_select 'span.error b', "Name"
|
102
101
|
end
|
103
102
|
|
103
|
+
test 'error adds aria-invalid attribute to inputs' do
|
104
|
+
with_form_for @user, :name, error: true
|
105
|
+
assert_select "input#user_name[name='user[name]'][aria-invalid='true']"
|
106
|
+
|
107
|
+
with_form_for @user, :name, as: :text, error: true
|
108
|
+
assert_select "textarea#user_name[name='user[name]'][aria-invalid='true']"
|
109
|
+
|
110
|
+
@user.errors.add(:active, 'must select one')
|
111
|
+
with_form_for @user, :active, as: :radio_buttons
|
112
|
+
assert_select "input#user_active_true[type=radio][name='user[active]'][aria-invalid='true']"
|
113
|
+
assert_select "input#user_active_false[type=radio][name='user[active]'][aria-invalid='true']"
|
114
|
+
|
115
|
+
with_form_for @user, :active, as: :check_boxes
|
116
|
+
assert_select "input#user_active_true[type=checkbox][aria-invalid='true']"
|
117
|
+
assert_select "input#user_active_false[type=checkbox][aria-invalid='true']"
|
118
|
+
|
119
|
+
with_form_for @user, :company_id, as: :select, error: true
|
120
|
+
assert_select "select#user_company_id[aria-invalid='true']"
|
121
|
+
|
122
|
+
@user.errors.add(:password, 'must not be blank')
|
123
|
+
with_form_for @user, :password
|
124
|
+
assert_select "input#user_password[type=password][aria-invalid='true']"
|
125
|
+
end
|
126
|
+
|
104
127
|
# FULL ERRORS
|
105
128
|
|
106
129
|
test 'full error generates a full error tag for the attribute' do
|
@@ -139,7 +139,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
139
139
|
|
140
140
|
test 'builder generates uuid fields for uuid columns' do
|
141
141
|
with_form_for @user, :uuid
|
142
|
-
|
142
|
+
if defined? ActiveModel::Type
|
143
|
+
assert_select 'form input#user_uuid.string.string'
|
144
|
+
else
|
145
|
+
assert_select 'form input#user_uuid.string.uuid'
|
146
|
+
end
|
143
147
|
end
|
144
148
|
|
145
149
|
test 'builder generates password fields for columns that matches password' do
|
@@ -121,6 +121,12 @@ class InputFieldTest < ActionView::TestCase
|
|
121
121
|
assert_no_select 'input.boolean[boolean_style]'
|
122
122
|
end
|
123
123
|
|
124
|
+
test 'build input_field does not treat "prompt" as a HTML attribute' do
|
125
|
+
with_input_field_for @user, :attempts, collection: [1,2,3,4,5], prompt: :translate
|
126
|
+
|
127
|
+
assert_no_select 'select[prompt]'
|
128
|
+
end
|
129
|
+
|
124
130
|
test 'build input_field without pattern component use the pattern string' do
|
125
131
|
swap_wrapper :default, custom_wrapper_with_html5_components do
|
126
132
|
with_input_field_for @user, :name, pattern: '\w+'
|
@@ -120,4 +120,11 @@ class LabelTest < ActionView::TestCase
|
|
120
120
|
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
test 'builder allows label specific `label_text` option' do
|
125
|
+
with_label_for @user, :time_zone, label_text: lambda { |l, _, _| "#{l.titleize}:" }
|
126
|
+
|
127
|
+
assert_no_select 'label[label_text]'
|
128
|
+
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
129
|
+
end
|
123
130
|
end
|
@@ -242,6 +242,38 @@ class WrapperTest < ActionView::TestCase
|
|
242
242
|
assert_select "section.custom_wrapper div.another_wrapper input.string"
|
243
243
|
end
|
244
244
|
|
245
|
+
test "input attributes class will merge with wrapper_options' classes" do
|
246
|
+
swap_wrapper :default, custom_wrapper_with_input_class do
|
247
|
+
with_concat_form_for @user do |f|
|
248
|
+
concat f.input :name, input_html: { class: 'another-class' }
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
assert_select "div.custom_wrapper input.string.inline-class.another-class"
|
253
|
+
end
|
254
|
+
|
255
|
+
test "input with data attributes will merge with wrapper_options' data" do
|
256
|
+
swap_wrapper :default, custom_wrapper_with_input_data_modal do
|
257
|
+
with_concat_form_for @user do |f|
|
258
|
+
concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
assert_select "input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']"
|
263
|
+
end
|
264
|
+
|
265
|
+
test "input with aria attributes will merge with wrapper_options' aria" do
|
266
|
+
skip unless ActionPack::VERSION::MAJOR == '4' && ActionPack::VERSION::MINOR >= '2'
|
267
|
+
|
268
|
+
swap_wrapper :default, custom_wrapper_with_input_aria_modal do
|
269
|
+
with_concat_form_for @user do |f|
|
270
|
+
concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
assert_select "input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']"
|
275
|
+
end
|
276
|
+
|
245
277
|
test 'input accepts attributes in the DSL' do
|
246
278
|
swap_wrapper :default, custom_wrapper_with_input_class do
|
247
279
|
with_concat_form_for @user do |f|
|
@@ -137,6 +137,14 @@ class BooleanInputTest < ActionView::TestCase
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
+
test 'input with nested style allows disabling hidden field' do
|
141
|
+
swap SimpleForm, boolean_style: :nested do
|
142
|
+
with_input_for @user, :active, :boolean, include_hidden: false
|
143
|
+
assert_select "label.boolean > input.boolean"
|
144
|
+
assert_no_select "input[type=hidden] + label.boolean"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
140
148
|
test 'input boolean works using :input only in wrapper config (no label_input)' do
|
141
149
|
swap_wrapper do
|
142
150
|
with_input_for @user, :active, :boolean
|
@@ -6,7 +6,11 @@ class DateTimeInputWithHtml5Test < ActionView::TestCase
|
|
6
6
|
test 'input generates a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
|
7
7
|
with_input_for @user, :created_at, :datetime, html5: true
|
8
8
|
|
9
|
-
|
9
|
+
if ActionPack::VERSION::STRING >= '5'
|
10
|
+
assert_select 'input[type="datetime-local"]'
|
11
|
+
elsif ActionPack::VERSION::STRING < '5'
|
12
|
+
assert_select 'input[type="datetime"]'
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
test 'input generates a datetime select for datetime attributes' do
|
@@ -76,7 +80,11 @@ class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
|
76
80
|
swap_wrapper do
|
77
81
|
with_input_for @user, :created_at, :datetime, html5: true
|
78
82
|
|
79
|
-
|
83
|
+
if ActionPack::VERSION::STRING >= '5'
|
84
|
+
assert_select 'input[type="datetime-local"]'
|
85
|
+
elsif ActionPack::VERSION::STRING < '5'
|
86
|
+
assert_select 'input[type="datetime"]'
|
87
|
+
end
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
@@ -14,6 +14,7 @@ class DiscoveryTest < ActionView::TestCase
|
|
14
14
|
Object.send :remove_const, :CustomizedInput
|
15
15
|
Object.send :remove_const, :DeprecatedInput
|
16
16
|
Object.send :remove_const, :CollectionSelectInput
|
17
|
+
CustomInputs.send :remove_const, :CustomizedInput
|
17
18
|
CustomInputs.send :remove_const, :PasswordInput
|
18
19
|
CustomInputs.send :remove_const, :NumericInput
|
19
20
|
end
|
@@ -113,6 +113,9 @@ class NumericInputTest < ActionView::TestCase
|
|
113
113
|
|
114
114
|
with_input_for @validating_user, :age, :integer
|
115
115
|
assert_select 'input[step="1"]'
|
116
|
+
|
117
|
+
with_input_for @validating_user, :age, :integer, as: :decimal, input_html: { step: 0.5 }
|
118
|
+
assert_select 'input[step="0.5"]'
|
116
119
|
end
|
117
120
|
|
118
121
|
test 'numeric input does not generate placeholder by default' do
|
@@ -5,14 +5,22 @@ class PriorityInputTest < ActionView::TestCase
|
|
5
5
|
test 'input generates a country select field' do
|
6
6
|
with_input_for @user, :country, :country
|
7
7
|
assert_select 'select#user_country'
|
8
|
-
|
8
|
+
if ActionPack::VERSION::STRING >= '5'
|
9
|
+
assert_select 'select option[value=BR]', 'Brazil'
|
10
|
+
elsif ActionPack::VERSION::STRING < '5'
|
11
|
+
assert_select 'select option[value=Brazil]', 'Brazil'
|
12
|
+
end
|
9
13
|
assert_no_select 'select option[value=""][disabled=disabled]'
|
10
14
|
end
|
11
15
|
|
12
16
|
test 'input generates a country select with SimpleForm default' do
|
13
17
|
swap SimpleForm, country_priority: [ 'Brazil' ] do
|
14
18
|
with_input_for @user, :country, :country
|
15
|
-
|
19
|
+
if ActionPack::VERSION::STRING >= '5'
|
20
|
+
assert_select 'select option[value="---------------"][disabled=disabled]'
|
21
|
+
elsif ActionPack::VERSION::STRING < '5'
|
22
|
+
assert_select 'select option[value=""][disabled=disabled]'
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
@@ -34,6 +34,38 @@ class RequiredTest < ActionView::TestCase
|
|
34
34
|
with_input_for @user, :name, :string
|
35
35
|
assert_select 'input[type=text].required'
|
36
36
|
assert_no_select 'input[type=text][required]'
|
37
|
+
assert_no_select 'input[type=text][aria-required]'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'when not using browser validations, when required option is set to false, input does not generate required html attribute' do
|
42
|
+
swap SimpleForm, browser_validations: false do
|
43
|
+
with_input_for @user, :name, :string, required: false
|
44
|
+
assert_no_select 'input[type=text].required'
|
45
|
+
assert_no_select 'input[type=text][required]'
|
46
|
+
assert_no_select 'input[type=text][aria-required]'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'when not using browser validations, when required option is set to true, input generates required html attribute' do
|
51
|
+
swap SimpleForm, browser_validations: false do
|
52
|
+
with_input_for @user, :name, :string, required: true
|
53
|
+
assert_select 'input[type=text].required'
|
54
|
+
assert_select 'input[type=text][required]'
|
55
|
+
assert_select 'input[type=text][aria-required]'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
test 'when not using browser validations, when required option is true in the wrapper, input does not generate required html attribute' do
|
60
|
+
swap SimpleForm, browser_validations: false do
|
61
|
+
swap_wrapper :default, self.custom_wrapper_with_required_input do
|
62
|
+
with_concat_form_for(@user) do |f|
|
63
|
+
concat f.input :name
|
64
|
+
end
|
65
|
+
assert_select 'input[type=text].required'
|
66
|
+
assert_no_select 'input[type=text][required]'
|
67
|
+
assert_no_select 'input[type=text][aria-required]'
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
39
71
|
|
@@ -32,9 +32,11 @@ class StringInputTest < ActionView::TestCase
|
|
32
32
|
assert_select 'input.string[maxlength="25"]'
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
if ActionPack::VERSION::STRING < '5'
|
36
|
+
test 'input does not get maxlength from validation when tokenizer present' do
|
37
|
+
with_input_for @validating_user, :action, :string
|
38
|
+
assert_no_select 'input.string[maxlength]'
|
39
|
+
end
|
38
40
|
end
|
39
41
|
|
40
42
|
test 'input gets maxlength from validation when :is option present' do
|
@@ -91,6 +91,20 @@ module MiscHelpers
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
def custom_wrapper_with_input_data_modal
|
95
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
96
|
+
b.use :label
|
97
|
+
b.use :input, data: { modal: 'data-modal', wrapper: 'data-wrapper' }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def custom_wrapper_with_input_aria_modal
|
102
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
103
|
+
b.use :label
|
104
|
+
b.use :input, aria: { modal: 'aria-modal', wrapper: 'aria-wrapper' }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
94
108
|
def custom_wrapper_with_label_class
|
95
109
|
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
96
110
|
b.use :label, class: 'inline-class'
|
data/test/support/models.rb
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
Association = Struct.new(:klass, :name, :macro, :scope, :options)
|
2
2
|
|
3
3
|
Column = Struct.new(:name, :type, :limit) do
|
4
|
-
# Returns +true+ if the column is either of type integer, float or decimal.
|
5
|
-
def number?
|
6
|
-
type == :integer || type == :float || type == :decimal
|
7
|
-
end
|
8
4
|
end
|
9
5
|
|
10
6
|
Relation = Struct.new(:records) do
|
@@ -130,6 +126,33 @@ class User
|
|
130
126
|
Column.new(attribute, column_type, limit)
|
131
127
|
end
|
132
128
|
|
129
|
+
begin
|
130
|
+
require 'active_model/type'
|
131
|
+
def type_for_attribute(attribute)
|
132
|
+
column_type, limit = case attribute.to_sym
|
133
|
+
when :name, :status, :password then [:string, 100]
|
134
|
+
when :description then [:text, 200]
|
135
|
+
when :age then :integer
|
136
|
+
when :credit_limit then [:decimal, 15]
|
137
|
+
when :active then :boolean
|
138
|
+
when :born_at then :date
|
139
|
+
when :delivery_time then :time
|
140
|
+
when :created_at then :datetime
|
141
|
+
when :updated_at then :datetime
|
142
|
+
when :lock_version then :integer
|
143
|
+
when :home_picture then :string
|
144
|
+
when :amount then :integer
|
145
|
+
when :attempts then :integer
|
146
|
+
when :action then :string
|
147
|
+
when :credit_card then :string
|
148
|
+
when :uuid then :string
|
149
|
+
end
|
150
|
+
|
151
|
+
ActiveModel::Type.lookup(column_type, limit: limit)
|
152
|
+
end
|
153
|
+
rescue LoadError
|
154
|
+
end
|
155
|
+
|
133
156
|
def has_attribute?(attribute)
|
134
157
|
case attribute.to_sym
|
135
158
|
when :name, :status, :password, :description, :age,
|
@@ -215,7 +238,9 @@ class ValidatingUser < User
|
|
215
238
|
only_integer: true
|
216
239
|
validates_length_of :name, maximum: 25
|
217
240
|
validates_length_of :description, maximum: 50
|
218
|
-
|
241
|
+
if ActionPack::VERSION::STRING < '5'
|
242
|
+
validates_length_of :action, maximum: 10, tokenizer: lambda { |str| str.scan(/\w+/) }
|
243
|
+
end
|
219
244
|
validates_length_of :home_picture, is: 12
|
220
245
|
|
221
246
|
def min_amount
|
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.
|
4
|
+
version: 3.3.0
|
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: 2016-08-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activemodel
|
@@ -178,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
178
|
version: '0'
|
179
179
|
requirements: []
|
180
180
|
rubyforge_project: simple_form
|
181
|
-
rubygems_version: 2.
|
181
|
+
rubygems_version: 2.6.3
|
182
182
|
signing_key:
|
183
183
|
specification_version: 4
|
184
184
|
summary: Forms made easy!
|