simple_form 3.5.0 → 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +38 -28
- data/lib/generators/simple_form/install_generator.rb +1 -0
- data/lib/generators/simple_form/templates/_form.html.erb +1 -0
- data/lib/generators/simple_form/templates/_form.html.haml +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +2 -1
- data/lib/simple_form.rb +8 -6
- data/lib/simple_form/action_view_extensions/builder.rb +1 -0
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -0
- data/lib/simple_form/components.rb +1 -0
- data/lib/simple_form/components/errors.rb +2 -1
- data/lib/simple_form/components/hints.rb +1 -0
- data/lib/simple_form/components/html5.rb +1 -0
- data/lib/simple_form/components/label_input.rb +2 -1
- data/lib/simple_form/components/labels.rb +2 -1
- data/lib/simple_form/components/maxlength.rb +1 -0
- data/lib/simple_form/components/min_max.rb +1 -0
- data/lib/simple_form/components/minlength.rb +2 -1
- data/lib/simple_form/components/pattern.rb +1 -0
- data/lib/simple_form/components/placeholders.rb +1 -0
- data/lib/simple_form/components/readonly.rb +1 -0
- data/lib/simple_form/error_notification.rb +1 -0
- data/lib/simple_form/form_builder.rb +9 -3
- data/lib/simple_form/helpers.rb +1 -0
- data/lib/simple_form/helpers/autofocus.rb +1 -0
- data/lib/simple_form/helpers/disabled.rb +1 -0
- data/lib/simple_form/helpers/readonly.rb +1 -0
- data/lib/simple_form/helpers/required.rb +1 -0
- data/lib/simple_form/helpers/validators.rb +2 -1
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs.rb +1 -0
- data/lib/simple_form/inputs/base.rb +2 -1
- data/lib/simple_form/inputs/block_input.rb +1 -0
- data/lib/simple_form/inputs/boolean_input.rb +3 -2
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
- data/lib/simple_form/inputs/collection_input.rb +3 -2
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -1
- data/lib/simple_form/inputs/collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/date_time_input.rb +1 -0
- data/lib/simple_form/inputs/file_input.rb +1 -0
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/hidden_input.rb +1 -0
- data/lib/simple_form/inputs/numeric_input.rb +1 -0
- data/lib/simple_form/inputs/password_input.rb +1 -0
- data/lib/simple_form/inputs/priority_input.rb +1 -0
- data/lib/simple_form/inputs/range_input.rb +1 -0
- data/lib/simple_form/inputs/string_input.rb +1 -0
- data/lib/simple_form/inputs/text_input.rb +1 -0
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +1 -0
- data/lib/simple_form/tags.rb +1 -0
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form/wrappers/builder.rb +1 -0
- data/lib/simple_form/wrappers/leaf.rb +2 -1
- data/lib/simple_form/wrappers/many.rb +1 -0
- data/lib/simple_form/wrappers/root.rb +1 -0
- data/lib/simple_form/wrappers/single.rb +2 -1
- data/test/action_view_extensions/builder_test.rb +6 -5
- data/test/action_view_extensions/form_helper_test.rb +3 -2
- data/test/components/label_test.rb +5 -4
- data/test/form_builder/association_test.rb +27 -2
- data/test/form_builder/button_test.rb +1 -0
- data/test/form_builder/error_notification_test.rb +1 -0
- data/test/form_builder/error_test.rb +6 -0
- data/test/form_builder/general_test.rb +10 -3
- data/test/form_builder/hint_test.rb +6 -0
- data/test/form_builder/input_field_test.rb +2 -1
- data/test/form_builder/label_test.rb +9 -3
- data/test/form_builder/wrapper_test.rb +3 -2
- data/test/generators/simple_form_generator_test.rb +4 -3
- data/test/inputs/boolean_input_test.rb +9 -0
- data/test/inputs/collection_check_boxes_input_test.rb +30 -14
- data/test/inputs/collection_radio_buttons_input_test.rb +40 -24
- data/test/inputs/collection_select_input_test.rb +40 -39
- data/test/inputs/datetime_input_test.rb +5 -4
- data/test/inputs/disabled_test.rb +1 -0
- data/test/inputs/discovery_test.rb +1 -0
- data/test/inputs/file_input_test.rb +1 -0
- data/test/inputs/general_test.rb +3 -2
- data/test/inputs/grouped_collection_select_input_test.rb +11 -10
- data/test/inputs/hidden_input_test.rb +1 -0
- data/test/inputs/numeric_input_test.rb +2 -1
- data/test/inputs/priority_input_test.rb +1 -0
- data/test/inputs/readonly_test.rb +1 -0
- data/test/inputs/required_test.rb +1 -0
- data/test/inputs/string_input_test.rb +2 -1
- data/test/inputs/text_input_test.rb +1 -0
- data/test/simple_form_test.rb +1 -0
- data/test/support/discovery_inputs.rb +1 -0
- data/test/support/misc_helpers.rb +2 -1
- data/test/support/mock_controller.rb +4 -0
- data/test/support/models.rb +36 -12
- data/test/test_helper.rb +2 -0
- metadata +3 -3
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class BooleanInput < Base
|
@@ -59,9 +60,9 @@ module SimpleForm
|
|
59
60
|
# we need the hidden field to be *outside* the label (otherwise it
|
60
61
|
# generates invalid html - html5 only).
|
61
62
|
def build_hidden_field_for_checkbox
|
62
|
-
return ""
|
63
|
+
return "" if !include_hidden? || !unchecked_value
|
63
64
|
options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }
|
64
|
-
options[:name] = input_html_options[:name] if input_html_options.
|
65
|
+
options[:name] = input_html_options[:name] if input_html_options.key?(:name)
|
65
66
|
|
66
67
|
@builder.hidden_field(attribute_name, options)
|
67
68
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class CollectionCheckBoxesInput < CollectionRadioButtonsInput
|
@@ -10,7 +11,7 @@ module SimpleForm
|
|
10
11
|
end
|
11
12
|
|
12
13
|
def build_nested_boolean_style_item_tag(collection_builder)
|
13
|
-
collection_builder.check_box + collection_builder.text
|
14
|
+
collection_builder.check_box + collection_builder.text.to_s
|
14
15
|
end
|
15
16
|
|
16
17
|
def item_wrapper_class
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class CollectionInput < Base
|
@@ -45,7 +46,7 @@ module SimpleForm
|
|
45
46
|
|
46
47
|
# Check if :include_blank must be included by default.
|
47
48
|
def skip_include_blank?
|
48
|
-
(options.keys & [
|
49
|
+
(options.keys & %i[prompt include_blank default selected]).any? || multiple?
|
49
50
|
end
|
50
51
|
|
51
52
|
def multiple?
|
@@ -89,7 +90,7 @@ module SimpleForm
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def detect_collection_classes(some_collection = collection)
|
92
|
-
some_collection.map
|
93
|
+
some_collection.map(&:class).uniq
|
93
94
|
end
|
94
95
|
|
95
96
|
def collection_includes_basic_objects?(collection_classes)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class CollectionRadioButtonsInput < CollectionInput
|
@@ -40,7 +41,7 @@ module SimpleForm
|
|
40
41
|
end
|
41
42
|
|
42
43
|
def build_nested_boolean_style_item_tag(collection_builder)
|
43
|
-
collection_builder.radio_button + collection_builder.text
|
44
|
+
collection_builder.radio_button + collection_builder.text.to_s
|
44
45
|
end
|
45
46
|
|
46
47
|
def item_wrapper_class
|
data/lib/simple_form/map_type.rb
CHANGED
data/lib/simple_form/railtie.rb
CHANGED
data/lib/simple_form/tags.rb
CHANGED
data/lib/simple_form/version.rb
CHANGED
data/lib/simple_form/wrappers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
class Leaf
|
@@ -11,7 +12,7 @@ module SimpleForm
|
|
11
12
|
def render(input)
|
12
13
|
method = input.method(@namespace)
|
13
14
|
|
14
|
-
if method.arity
|
15
|
+
if method.arity.zero?
|
15
16
|
ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
|
16
17
|
|
17
18
|
method.call
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# `Single` is an optimization for a wrapper that has only one component.
|
@@ -19,7 +20,7 @@ module SimpleForm
|
|
19
20
|
private
|
20
21
|
|
21
22
|
def html_options(options)
|
22
|
-
[
|
23
|
+
%i[label input].include?(namespace) ? {} : super
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
class BuilderTest < ActionView::TestCase
|
@@ -36,7 +37,7 @@ class BuilderTest < ActionView::TestCase
|
|
36
37
|
end
|
37
38
|
|
38
39
|
test "collection radio handles camelized collection values for labels correctly" do
|
39
|
-
with_collection_radio_buttons @user, :active, [
|
40
|
+
with_collection_radio_buttons @user, :active, %w[Yes No], :to_s, :to_s
|
40
41
|
|
41
42
|
assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'
|
42
43
|
assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
|
@@ -243,7 +244,7 @@ class BuilderTest < ActionView::TestCase
|
|
243
244
|
|
244
245
|
test "collection radio with block helpers does not leak the template" do
|
245
246
|
with_concat_form_for(@user) do |f|
|
246
|
-
collection_input =
|
247
|
+
collection_input = f.collection_radio_buttons :active, [true, false], :to_s, :to_s do |b|
|
247
248
|
b.label(class: b.object) { b.radio_button + b.text }
|
248
249
|
end
|
249
250
|
concat collection_input
|
@@ -283,7 +284,7 @@ class BuilderTest < ActionView::TestCase
|
|
283
284
|
end
|
284
285
|
|
285
286
|
test "collection check box handles camelized collection values for labels correctly" do
|
286
|
-
with_collection_check_boxes @user, :active, [
|
287
|
+
with_collection_check_boxes @user, :active, %w[Yes No], :to_s, :to_s
|
287
288
|
|
288
289
|
assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
|
289
290
|
assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
|
@@ -317,7 +318,7 @@ class BuilderTest < ActionView::TestCase
|
|
317
318
|
|
318
319
|
test "collection check boxes accepts selected string values as :checked option" do
|
319
320
|
collection = (1..3).map { |i| [i, "Category #{i}"] }
|
320
|
-
with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: [
|
321
|
+
with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: %w[1 3]
|
321
322
|
|
322
323
|
assert_select 'input[type=checkbox][value="1"][checked=checked]'
|
323
324
|
assert_select 'input[type=checkbox][value="3"][checked=checked]'
|
@@ -541,7 +542,7 @@ class BuilderTest < ActionView::TestCase
|
|
541
542
|
|
542
543
|
test "collection check boxes with block helpers does not leak the template" do
|
543
544
|
with_concat_form_for(@user) do |f|
|
544
|
-
collection_input =
|
545
|
+
collection_input = f.collection_check_boxes :active, [true, false], :to_s, :to_s do |b|
|
545
546
|
b.label(class: b.object) { b.check_box + b.text }
|
546
547
|
end
|
547
548
|
concat collection_input
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
class FormHelperTest < ActionView::TestCase
|
@@ -151,7 +152,7 @@ class FormHelperTest < ActionView::TestCase
|
|
151
152
|
end
|
152
153
|
|
153
154
|
test 'SimpleForm for swaps default action view field_error_proc' do
|
154
|
-
expected_error_proc =
|
155
|
+
expected_error_proc = -> {}
|
155
156
|
swap SimpleForm, field_error_proc: expected_error_proc do
|
156
157
|
simple_form_for :user do |f|
|
157
158
|
assert_equal expected_error_proc, ::ActionView::Base.field_error_proc
|
@@ -161,7 +162,7 @@ class FormHelperTest < ActionView::TestCase
|
|
161
162
|
|
162
163
|
private
|
163
164
|
|
164
|
-
def swap_field_error_proc(expected_error_proc =
|
165
|
+
def swap_field_error_proc(expected_error_proc = -> {})
|
165
166
|
swap ActionView::Base, field_error_proc: expected_error_proc do
|
166
167
|
yield
|
167
168
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -177,7 +178,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
177
178
|
end
|
178
179
|
|
179
180
|
test 'label does not have css class from type when generate_additional_classes_for does not include :label' do
|
180
|
-
swap SimpleForm, generate_additional_classes_for: [
|
181
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
181
182
|
with_label_for @user, :name, :string
|
182
183
|
assert_no_select 'label.string'
|
183
184
|
with_label_for @user, :description, :text
|
@@ -192,7 +193,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
192
193
|
end
|
193
194
|
|
194
195
|
test 'label does not generate empty css class' do
|
195
|
-
swap SimpleForm, generate_additional_classes_for: [
|
196
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
196
197
|
with_label_for @user, :name, :string
|
197
198
|
assert_no_select 'label[class]'
|
198
199
|
end
|
@@ -206,7 +207,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
206
207
|
end
|
207
208
|
|
208
209
|
test 'label does not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do
|
209
|
-
swap SimpleForm, generate_additional_classes_for: [
|
210
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
210
211
|
with_label_for @validating_user, :name, :string
|
211
212
|
assert_no_select 'label.required'
|
212
213
|
with_label_for @validating_user, :status, :string
|
@@ -289,7 +290,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
289
290
|
end
|
290
291
|
|
291
292
|
test 'label includes for attribute for select collection' do
|
292
|
-
with_label_for @user, :sex, :select, collection: [
|
293
|
+
with_label_for @user, :sex, :select, collection: %i[male female]
|
293
294
|
assert_select 'label[for=user_sex]'
|
294
295
|
end
|
295
296
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -14,6 +15,12 @@ class AssociationTest < ActionView::TestCase
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
test 'builder association works with decorated object responsive to #to_model' do
|
19
|
+
assert_nothing_raised do
|
20
|
+
with_association_for @decorated_user, :company
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
test 'builder association with a block calls simple_fields_for' do
|
18
25
|
simple_form_for @user do |f|
|
19
26
|
f.association :posts do |posts_form|
|
@@ -121,6 +128,15 @@ class AssociationTest < ActionView::TestCase
|
|
121
128
|
assert_no_select 'form select option[value="2"]'
|
122
129
|
end
|
123
130
|
|
131
|
+
test 'builder allows collection to have a scope with parameter' do
|
132
|
+
with_association_for @user, :special_tags
|
133
|
+
assert_select 'form select.select#user_special_tag_ids'
|
134
|
+
assert_select 'form select[multiple=multiple]'
|
135
|
+
assert_select 'form select option[value="1"]', 'Tag 1'
|
136
|
+
assert_no_select 'form select option[value="2"]'
|
137
|
+
assert_no_select 'form select option[value="3"]'
|
138
|
+
end
|
139
|
+
|
124
140
|
test 'builder marks the record which already belongs to the user' do
|
125
141
|
@user.company_id = 2
|
126
142
|
with_association_for @user, :company, as: :radio_buttons
|
@@ -154,6 +170,15 @@ class AssociationTest < ActionView::TestCase
|
|
154
170
|
end
|
155
171
|
end
|
156
172
|
|
173
|
+
test 'builder does not call where if the given association does not respond to it' do
|
174
|
+
with_association_for @user, :friends
|
175
|
+
assert_select 'form select.select#user_friend_ids'
|
176
|
+
assert_select 'form select[multiple=multiple]'
|
177
|
+
assert_select 'form select option[value="1"]', 'Friend 1'
|
178
|
+
assert_select 'form select option[value="2"]', 'Friend 2'
|
179
|
+
assert_select 'form select option[value="3"]', 'Friend 3'
|
180
|
+
end
|
181
|
+
|
157
182
|
test 'builder does not call order if the given association does not respond to it' do
|
158
183
|
with_association_for @user, :pictures
|
159
184
|
assert_select 'form select.select#user_picture_ids'
|
@@ -210,12 +235,12 @@ class AssociationTest < ActionView::TestCase
|
|
210
235
|
end
|
211
236
|
|
212
237
|
test 'builder with collection support does not change the options hash' do
|
213
|
-
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li}
|
238
|
+
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li }
|
214
239
|
with_association_for @user, :tags, options
|
215
240
|
|
216
241
|
assert_select 'form ul', count: 1
|
217
242
|
assert_select 'form ul li', count: 3
|
218
|
-
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li},
|
243
|
+
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li },
|
219
244
|
options)
|
220
245
|
end
|
221
246
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.error and f.full_error
|
@@ -35,6 +36,11 @@ class ErrorTest < ActionView::TestCase
|
|
35
36
|
assert_select 'span.error', "cannot be blank"
|
36
37
|
end
|
37
38
|
|
39
|
+
test 'error generates messages with decorated object responsive to #to_model' do
|
40
|
+
with_error_for @decorated_user, :name
|
41
|
+
assert_select 'span.error', "cannot be blank"
|
42
|
+
end
|
43
|
+
|
38
44
|
test 'error generates messages for attribute with one error when using first' do
|
39
45
|
swap SimpleForm, error_method: :first do
|
40
46
|
with_error_for @user, :age
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -30,6 +31,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
34
|
+
test 'builder works with decorated object responsive to #to_model' do
|
35
|
+
assert_nothing_raised do
|
36
|
+
with_form_for @decorated_user, :name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
33
40
|
test 'builder input allows a block to configure input' do
|
34
41
|
with_form_for @user, :name do
|
35
42
|
text_field_tag :foo, :bar, id: :cool
|
@@ -49,7 +56,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
49
56
|
test 'builder does not override custom input mappings for custom collection' do
|
50
57
|
swap SimpleForm, input_mappings: { /gender$/ => :check_boxes } do
|
51
58
|
with_concat_form_for @user do |f|
|
52
|
-
f.input :gender, collection: [
|
59
|
+
f.input :gender, collection: %i[male female]
|
53
60
|
end
|
54
61
|
|
55
62
|
assert_no_select 'select option', 'Male'
|
@@ -58,7 +65,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
58
65
|
end
|
59
66
|
|
60
67
|
test 'builder allows to skip input_type class' do
|
61
|
-
swap SimpleForm, generate_additional_classes_for: [
|
68
|
+
swap SimpleForm, generate_additional_classes_for: %i[label wrapper] do
|
62
69
|
with_form_for @user, :post_count
|
63
70
|
assert_no_select "form input#user_post_count.integer"
|
64
71
|
assert_select "form input#user_post_count"
|
@@ -382,7 +389,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
382
389
|
end
|
383
390
|
|
384
391
|
# DEFAULT OPTIONS
|
385
|
-
[
|
392
|
+
%i[input input_field].each do |method|
|
386
393
|
test "builder receives a default argument and pass it to the inputs when calling '#{method}'" do
|
387
394
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
|
388
395
|
f.public_send(method, :name)
|