simple_form 3.0.0 → 3.1.0.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -22
- data/MIT-LICENSE +1 -1
- data/README.md +146 -71
- data/lib/generators/simple_form/install_generator.rb +2 -2
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/simple_form/components/errors.rb +30 -2
- data/lib/simple_form/components/hints.rb +8 -3
- data/lib/simple_form/components/html5.rb +1 -1
- data/lib/simple_form/components/label_input.rb +20 -2
- data/lib/simple_form/components/labels.rb +9 -5
- data/lib/simple_form/components/maxlength.rb +1 -1
- data/lib/simple_form/components/min_max.rb +1 -1
- data/lib/simple_form/components/pattern.rb +1 -1
- data/lib/simple_form/components/placeholders.rb +2 -2
- data/lib/simple_form/components/readonly.rb +1 -1
- data/lib/simple_form/form_builder.rb +92 -57
- data/lib/simple_form/helpers.rb +5 -5
- data/lib/simple_form/inputs/base.rb +36 -11
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +23 -13
- data/lib/simple_form/inputs/collection_input.rb +32 -9
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
- data/lib/simple_form/inputs/collection_select_input.rb +4 -2
- data/lib/simple_form/inputs/date_time_input.rb +12 -2
- data/lib/simple_form/inputs/file_input.rb +4 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
- data/lib/simple_form/inputs/hidden_input.rb +4 -2
- data/lib/simple_form/inputs/numeric_input.rb +5 -4
- data/lib/simple_form/inputs/password_input.rb +4 -2
- data/lib/simple_form/inputs/priority_input.rb +4 -2
- data/lib/simple_form/inputs/range_input.rb +1 -1
- data/lib/simple_form/inputs/string_input.rb +4 -2
- data/lib/simple_form/inputs/text_input.rb +4 -2
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +7 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers/builder.rb +5 -5
- data/lib/simple_form/wrappers/leaf.rb +28 -0
- data/lib/simple_form/wrappers/many.rb +5 -6
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers/single.rb +5 -3
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form.rb +38 -6
- data/test/action_view_extensions/builder_test.rb +2 -2
- data/test/components/label_test.rb +1 -1
- data/test/form_builder/association_test.rb +17 -0
- data/test/form_builder/error_notification_test.rb +1 -1
- data/test/form_builder/error_test.rb +67 -1
- data/test/form_builder/hint_test.rb +8 -2
- data/test/form_builder/input_field_test.rb +25 -1
- data/test/form_builder/label_test.rb +34 -1
- data/test/form_builder/wrapper_test.rb +67 -0
- data/test/generators/simple_form_generator_test.rb +2 -2
- data/test/inputs/boolean_input_test.rb +50 -2
- data/test/inputs/collection_check_boxes_input_test.rb +40 -11
- data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
- data/test/inputs/collection_select_input_test.rb +108 -3
- data/test/inputs/datetime_input_test.rb +105 -38
- data/test/inputs/discovery_test.rb +12 -1
- data/test/inputs/grouped_collection_select_input_test.rb +36 -0
- data/test/inputs/string_input_test.rb +20 -0
- data/test/simple_form_test.rb +8 -0
- data/test/support/discovery_inputs.rb +12 -2
- data/test/support/misc_helpers.rb +49 -5
- data/test/support/models.rb +49 -24
- data/test/test_helper.rb +2 -0
- metadata +23 -37
- data/lib/simple_form/action_view_extensions/builder.rb.orig +0 -247
- data/lib/simple_form/form_builder.rb.orig +0 -486
- data/lib/simple_form/version.rb.orig +0 -7
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
module SimpleForm
|
|
2
2
|
module Inputs
|
|
3
3
|
class GroupedCollectionSelectInput < CollectionInput
|
|
4
|
-
def input
|
|
4
|
+
def input(wrapper_options = nil)
|
|
5
5
|
label_method, value_method = detect_collection_methods
|
|
6
|
+
|
|
7
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
8
|
+
|
|
6
9
|
@builder.grouped_collection_select(attribute_name, grouped_collection,
|
|
7
10
|
group_method, group_label_method, value_method, label_method,
|
|
8
|
-
input_options,
|
|
11
|
+
input_options, merged_input_options)
|
|
9
12
|
end
|
|
10
13
|
|
|
11
14
|
private
|
|
@@ -19,7 +22,7 @@ module SimpleForm
|
|
|
19
22
|
|
|
20
23
|
# Sample collection
|
|
21
24
|
def collection
|
|
22
|
-
@collection ||= grouped_collection.
|
|
25
|
+
@collection ||= grouped_collection.map { |collection| collection.try(:send, group_method) }.detect(&:present?) || []
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def group_method
|
|
@@ -36,6 +39,15 @@ module SimpleForm
|
|
|
36
39
|
|
|
37
40
|
label
|
|
38
41
|
end
|
|
42
|
+
|
|
43
|
+
def detect_method_from_class(collection_classes)
|
|
44
|
+
return {} if collection_classes.empty?
|
|
45
|
+
|
|
46
|
+
sample = collection_classes.first
|
|
47
|
+
|
|
48
|
+
{ label: SimpleForm.collection_label_methods.find { |m| sample.instance_methods.include?(m) },
|
|
49
|
+
value: SimpleForm.collection_value_methods.find { |m| sample.instance_methods.include?(m) } }
|
|
50
|
+
end
|
|
39
51
|
end
|
|
40
52
|
end
|
|
41
53
|
end
|
|
@@ -3,8 +3,10 @@ module SimpleForm
|
|
|
3
3
|
class HiddenInput < Base
|
|
4
4
|
disable :label, :errors, :hint, :required
|
|
5
5
|
|
|
6
|
-
def input
|
|
7
|
-
|
|
6
|
+
def input(wrapper_options = nil)
|
|
7
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
8
|
+
|
|
9
|
+
@builder.hidden_field(attribute_name, merged_input_options)
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
private
|
|
@@ -3,16 +3,17 @@ module SimpleForm
|
|
|
3
3
|
class NumericInput < Base
|
|
4
4
|
enable :placeholder, :min_max
|
|
5
5
|
|
|
6
|
-
def input
|
|
6
|
+
def input(wrapper_options = nil)
|
|
7
7
|
input_html_classes.unshift("numeric")
|
|
8
8
|
if html5?
|
|
9
9
|
input_html_options[:type] ||= "number"
|
|
10
10
|
input_html_options[:step] ||= integer? ? 1 : "any"
|
|
11
11
|
end
|
|
12
|
-
@builder.text_field(attribute_name, input_html_options)
|
|
13
|
-
end
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
14
|
+
|
|
15
|
+
@builder.text_field(attribute_name, merged_input_options)
|
|
16
|
+
end
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
@@ -3,8 +3,10 @@ module SimpleForm
|
|
|
3
3
|
class PasswordInput < Base
|
|
4
4
|
enable :placeholder, :maxlength
|
|
5
5
|
|
|
6
|
-
def input
|
|
7
|
-
|
|
6
|
+
def input(wrapper_options = nil)
|
|
7
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
8
|
+
|
|
9
|
+
@builder.password_field(attribute_name, merged_input_options)
|
|
8
10
|
end
|
|
9
11
|
end
|
|
10
12
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
module SimpleForm
|
|
2
2
|
module Inputs
|
|
3
3
|
class PriorityInput < CollectionSelectInput
|
|
4
|
-
def input
|
|
4
|
+
def input(wrapper_options = nil)
|
|
5
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
6
|
+
|
|
5
7
|
@builder.send(:"#{input_type}_select", attribute_name, input_priority,
|
|
6
|
-
input_options,
|
|
8
|
+
input_options, merged_input_options)
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def input_priority
|
|
@@ -3,13 +3,15 @@ module SimpleForm
|
|
|
3
3
|
class StringInput < Base
|
|
4
4
|
enable :placeholder, :maxlength, :pattern
|
|
5
5
|
|
|
6
|
-
def input
|
|
6
|
+
def input(wrapper_options = nil)
|
|
7
7
|
unless string?
|
|
8
8
|
input_html_classes.unshift("string")
|
|
9
9
|
input_html_options[:type] ||= input_type if html5?
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
13
|
+
|
|
14
|
+
@builder.text_field(attribute_name, merged_input_options)
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
private
|
|
@@ -3,8 +3,10 @@ module SimpleForm
|
|
|
3
3
|
class TextInput < Base
|
|
4
4
|
enable :placeholder, :maxlength
|
|
5
5
|
|
|
6
|
-
def input
|
|
7
|
-
|
|
6
|
+
def input(wrapper_options = nil)
|
|
7
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
|
8
|
+
|
|
9
|
+
@builder.text_area(attribute_name, merged_input_options)
|
|
8
10
|
end
|
|
9
11
|
end
|
|
10
12
|
end
|
data/lib/simple_form/railtie.rb
CHANGED
|
@@ -3,5 +3,12 @@ require 'rails/railtie'
|
|
|
3
3
|
module SimpleForm
|
|
4
4
|
class Railtie < Rails::Railtie
|
|
5
5
|
config.eager_load_namespaces << SimpleForm
|
|
6
|
+
|
|
7
|
+
config.after_initialize do
|
|
8
|
+
unless SimpleForm.configured?
|
|
9
|
+
warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +
|
|
10
|
+
' Use `rails generate simple_form:install` to generate the Simple Form configuration.'
|
|
11
|
+
end
|
|
12
|
+
end
|
|
6
13
|
end
|
|
7
14
|
end
|
data/lib/simple_form/tags.rb
CHANGED
|
@@ -15,6 +15,13 @@ module SimpleForm
|
|
|
15
15
|
|
|
16
16
|
rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)
|
|
17
17
|
|
|
18
|
+
if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
|
|
19
|
+
label_options = {}
|
|
20
|
+
add_default_name_and_id_for_value(value, label_options)
|
|
21
|
+
label_options['for'] = label_options.delete('id')
|
|
22
|
+
rendered_item = content_tag(:label, rendered_item, label_options)
|
|
23
|
+
end
|
|
24
|
+
|
|
18
25
|
item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item
|
|
19
26
|
end.join.html_safe
|
|
20
27
|
end
|
data/lib/simple_form/version.rb
CHANGED
|
@@ -45,20 +45,20 @@ module SimpleForm
|
|
|
45
45
|
@components = []
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def use(name, options=
|
|
48
|
+
def use(name, options = {}, &block)
|
|
49
49
|
if options && wrapper = options[:wrap_with]
|
|
50
|
-
@components << Single.new(name, wrapper)
|
|
50
|
+
@components << Single.new(name, wrapper, options.except(:wrap_with))
|
|
51
51
|
else
|
|
52
|
-
@components << name
|
|
52
|
+
@components << Leaf.new(name, options)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def optional(name, options=
|
|
56
|
+
def optional(name, options = {}, &block)
|
|
57
57
|
@options[name] = false
|
|
58
58
|
use(name, options, &block)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def wrapper(name, options=nil)
|
|
61
|
+
def wrapper(name, options = nil)
|
|
62
62
|
if block_given?
|
|
63
63
|
name, options = nil, name if name.is_a?(Hash)
|
|
64
64
|
builder = self.class.new(@options)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module Wrappers
|
|
3
|
+
class Leaf
|
|
4
|
+
attr_reader :namespace
|
|
5
|
+
|
|
6
|
+
def initialize(namespace, options = {})
|
|
7
|
+
@namespace = namespace
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def render(input)
|
|
12
|
+
method = input.method(@namespace)
|
|
13
|
+
|
|
14
|
+
if method.arity == 0
|
|
15
|
+
ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
|
|
16
|
+
|
|
17
|
+
method.call
|
|
18
|
+
else
|
|
19
|
+
method.call(@options)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def find(name)
|
|
24
|
+
self if @namespace == name
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module SimpleForm
|
|
2
2
|
module Wrappers
|
|
3
3
|
# A wrapper is an object that holds several components and render them.
|
|
4
|
-
# A component may
|
|
4
|
+
# A component may be any object that responds to `render`.
|
|
5
5
|
# This API allows inputs/components to be easily wrapped, removing the
|
|
6
6
|
# need to modify the code only to wrap input in an extra tag.
|
|
7
7
|
#
|
|
@@ -10,9 +10,8 @@ module SimpleForm
|
|
|
10
10
|
# on demand on input generation.
|
|
11
11
|
class Many
|
|
12
12
|
attr_reader :namespace, :defaults, :components
|
|
13
|
-
alias :to_sym :namespace
|
|
14
13
|
|
|
15
|
-
def initialize(namespace, components, defaults={})
|
|
14
|
+
def initialize(namespace, components, defaults = {})
|
|
16
15
|
@namespace = namespace
|
|
17
16
|
@components = components
|
|
18
17
|
@defaults = defaults
|
|
@@ -25,8 +24,8 @@ module SimpleForm
|
|
|
25
24
|
options = input.options
|
|
26
25
|
|
|
27
26
|
components.each do |component|
|
|
28
|
-
next if options[component] == false
|
|
29
|
-
rendered = component.
|
|
27
|
+
next if options[component.namespace] == false
|
|
28
|
+
rendered = component.render(input)
|
|
30
29
|
content.safe_concat rendered.to_s if rendered
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -62,7 +61,7 @@ module SimpleForm
|
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
def html_options(options)
|
|
65
|
-
options[:"#{namespace}_html"] || {}
|
|
64
|
+
(@defaults[:html] || {}).merge(options[:"#{namespace}_html"] || {})
|
|
66
65
|
end
|
|
67
66
|
|
|
68
67
|
def html_classes(input, options)
|
|
@@ -2,14 +2,16 @@ module SimpleForm
|
|
|
2
2
|
module Wrappers
|
|
3
3
|
# `Single` is an optimization for a wrapper that has only one component.
|
|
4
4
|
class Single < Many
|
|
5
|
-
def initialize(name, options={})
|
|
6
|
-
|
|
5
|
+
def initialize(name, wrapper_options = {}, options = {})
|
|
6
|
+
@component = Leaf.new(name, options)
|
|
7
|
+
|
|
8
|
+
super(name, [@component], wrapper_options)
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def render(input)
|
|
10
12
|
options = input.options
|
|
11
13
|
if options[namespace] != false
|
|
12
|
-
content =
|
|
14
|
+
content = @component.render(input)
|
|
13
15
|
wrap(input, options, content) if content
|
|
14
16
|
end
|
|
15
17
|
end
|
data/lib/simple_form/wrappers.rb
CHANGED
data/lib/simple_form.rb
CHANGED
|
@@ -24,6 +24,24 @@ module SimpleForm
|
|
|
24
24
|
SimpleForm::Components.eager_load!
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN
|
|
28
|
+
%{name} method now accepts a `wrapper_options` argument. The method definition without the argument is deprecated and will be removed in the next Simple Form version. Change your code from:
|
|
29
|
+
|
|
30
|
+
def %{name}
|
|
31
|
+
|
|
32
|
+
to
|
|
33
|
+
|
|
34
|
+
def %{name}(wrapper_options)
|
|
35
|
+
|
|
36
|
+
See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
37
|
+
WARN
|
|
38
|
+
|
|
39
|
+
@@configured = false
|
|
40
|
+
|
|
41
|
+
def self.configured? #:nodoc:
|
|
42
|
+
@@configured
|
|
43
|
+
end
|
|
44
|
+
|
|
27
45
|
## CONFIGURATION OPTIONS
|
|
28
46
|
|
|
29
47
|
# Method used to tidy up errors.
|
|
@@ -66,7 +84,7 @@ module SimpleForm
|
|
|
66
84
|
|
|
67
85
|
# How the label text should be generated altogether with the required text.
|
|
68
86
|
mattr_accessor :label_text
|
|
69
|
-
@@label_text = lambda { |label, required| "#{required} #{label}" }
|
|
87
|
+
@@label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
|
|
70
88
|
|
|
71
89
|
# You can define the class to be used on all labels. Defaults to none.
|
|
72
90
|
mattr_accessor :label_class
|
|
@@ -107,6 +125,8 @@ module SimpleForm
|
|
|
107
125
|
# Custom wrappers for input types. This should be a hash containing an input
|
|
108
126
|
# type as key and the wrapper that will be used for all inputs with specified type.
|
|
109
127
|
# e.g { string: :string_wrapper, boolean: :boolean_wrapper }
|
|
128
|
+
# You can also set a wrapper mapping per form basis.
|
|
129
|
+
# e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox })
|
|
110
130
|
mattr_accessor :wrapper_mappings
|
|
111
131
|
@@wrapper_mappings = nil
|
|
112
132
|
|
|
@@ -151,15 +171,26 @@ module SimpleForm
|
|
|
151
171
|
mattr_accessor :input_class
|
|
152
172
|
@@input_class = nil
|
|
153
173
|
|
|
174
|
+
# Defines if an input wrapper class should be included or not
|
|
175
|
+
mattr_accessor :include_default_input_wrapper_class
|
|
176
|
+
@@include_default_input_wrapper_class = true
|
|
177
|
+
|
|
178
|
+
# Define the default class of the input wrapper of the boolean input.
|
|
179
|
+
mattr_accessor :boolean_label_class
|
|
180
|
+
@@boolean_label_class = 'checkbox'
|
|
181
|
+
|
|
154
182
|
## WRAPPER CONFIGURATION
|
|
155
183
|
# The default wrapper to be used by the FormBuilder.
|
|
156
184
|
mattr_accessor :default_wrapper
|
|
157
185
|
@@default_wrapper = :default
|
|
158
|
-
@@wrappers = {}
|
|
186
|
+
@@wrappers = {} #:nodoc:
|
|
187
|
+
|
|
188
|
+
mattr_accessor :i18n_scope
|
|
189
|
+
@@i18n_scope = 'simple_form'
|
|
159
190
|
|
|
160
191
|
# Retrieves a given wrapper
|
|
161
192
|
def self.wrapper(name)
|
|
162
|
-
@@wrappers[name.
|
|
193
|
+
@@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
|
|
163
194
|
end
|
|
164
195
|
|
|
165
196
|
# Raised when fails to find a given wrapper name
|
|
@@ -172,14 +203,14 @@ module SimpleForm
|
|
|
172
203
|
if block_given?
|
|
173
204
|
options = args.extract_options!
|
|
174
205
|
name = args.first || :default
|
|
175
|
-
@@wrappers[name.
|
|
206
|
+
@@wrappers[name.to_s] = build(options, &block)
|
|
176
207
|
else
|
|
177
208
|
@@wrappers
|
|
178
209
|
end
|
|
179
210
|
end
|
|
180
211
|
|
|
181
212
|
# Builds a new wrapper using SimpleForm::Wrappers::Builder.
|
|
182
|
-
def self.build(options={})
|
|
213
|
+
def self.build(options = {})
|
|
183
214
|
options[:tag] = :div if options[:tag].nil?
|
|
184
215
|
builder = SimpleForm::Wrappers::Builder.new(options)
|
|
185
216
|
yield builder
|
|
@@ -210,9 +241,10 @@ module SimpleForm
|
|
|
210
241
|
ActiveSupport::Deprecation.warn "[SIMPLE_FORM] SimpleForm.default_input_size= is deprecated and has no effect", caller
|
|
211
242
|
end
|
|
212
243
|
|
|
213
|
-
# Default way to setup
|
|
244
|
+
# Default way to setup Simple Form. Run rails generate simple_form:install
|
|
214
245
|
# to create a fresh initializer with all configuration values.
|
|
215
246
|
def self.setup
|
|
247
|
+
@@configured = true
|
|
216
248
|
yield self
|
|
217
249
|
end
|
|
218
250
|
end
|
|
@@ -8,13 +8,13 @@ class BuilderTest < ActionView::TestCase
|
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
|
|
11
|
+
def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
12
12
|
with_concat_form_for(object) do |f|
|
|
13
13
|
f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
|
|
17
|
+
def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
|
18
18
|
with_concat_form_for(object) do |f|
|
|
19
19
|
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
|
|
20
20
|
end
|
|
@@ -7,7 +7,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
|
7
7
|
SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def with_label_for(object, attribute_name, type, options={})
|
|
10
|
+
def with_label_for(object, attribute_name, type, options = {})
|
|
11
11
|
with_concat_form_for(object) do |f|
|
|
12
12
|
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
|
13
13
|
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
|
|
@@ -113,6 +113,14 @@ class AssociationTest < ActionView::TestCase
|
|
|
113
113
|
assert_no_select 'form select option[value=3]'
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
test 'builder allows collection to have a scope' do
|
|
117
|
+
with_association_for @user, :special_pictures
|
|
118
|
+
assert_select 'form select.select#user_special_picture_ids'
|
|
119
|
+
assert_select 'form select option[value=3]', '3'
|
|
120
|
+
assert_no_select 'form select option[value=1]'
|
|
121
|
+
assert_no_select 'form select option[value=2]'
|
|
122
|
+
end
|
|
123
|
+
|
|
116
124
|
test 'builder marks the record which already belongs to the user' do
|
|
117
125
|
@user.company_id = 2
|
|
118
126
|
with_association_for @user, :company, as: :radio_buttons
|
|
@@ -146,6 +154,15 @@ class AssociationTest < ActionView::TestCase
|
|
|
146
154
|
end
|
|
147
155
|
end
|
|
148
156
|
|
|
157
|
+
test 'builder does not call order if the given association does not respond to it' do
|
|
158
|
+
with_association_for @user, :pictures
|
|
159
|
+
assert_select 'form select.select#user_picture_ids'
|
|
160
|
+
assert_select 'form select[multiple=multiple]'
|
|
161
|
+
assert_select 'form select option[value=1]', 'Picture 1'
|
|
162
|
+
assert_select 'form select option[value=2]', 'Picture 2'
|
|
163
|
+
assert_select 'form select option[value=3]', 'Picture 3'
|
|
164
|
+
end
|
|
165
|
+
|
|
149
166
|
test 'builder creates a select with multiple options for collection associations' do
|
|
150
167
|
with_association_for @user, :tags
|
|
151
168
|
assert_select 'form select.select#user_tag_ids'
|
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
|
3
3
|
|
|
4
4
|
# Tests for f.error_notification
|
|
5
5
|
class ErrorNotificationTest < ActionView::TestCase
|
|
6
|
-
def with_error_notification_for(object, options={}, &block)
|
|
6
|
+
def with_error_notification_for(object, options = {}, &block)
|
|
7
7
|
with_concat_form_for(object) do |f|
|
|
8
8
|
f.error_notification(options)
|
|
9
9
|
end
|
|
@@ -80,8 +80,13 @@ class ErrorTest < ActionView::TestCase
|
|
|
80
80
|
assert_no_select 'p.error[error_method]'
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
test 'error should
|
|
83
|
+
test 'error should escape error prefix text' do
|
|
84
84
|
with_error_for @user, :name, error_prefix: '<b>Name</b>'
|
|
85
|
+
assert_select 'span.error', "<b>Name</b> can't be blank"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
test 'error should generate an error message with raw HTML tags' do
|
|
89
|
+
with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
|
|
85
90
|
assert_select 'span.error', "Name can't be blank"
|
|
86
91
|
assert_select 'span.error b', "Name"
|
|
87
92
|
end
|
|
@@ -118,4 +123,65 @@ class ErrorTest < ActionView::TestCase
|
|
|
118
123
|
assert_select 'span.omg_error', "can't be blank"
|
|
119
124
|
end
|
|
120
125
|
end
|
|
126
|
+
|
|
127
|
+
# FULL_ERROR_WRAPPER
|
|
128
|
+
|
|
129
|
+
test 'full error should find errors on association' do
|
|
130
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
|
131
|
+
with_form_for @user, :company_id, as: :select
|
|
132
|
+
assert_select 'span.error', 'Company must be valid'
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
test 'full error can be disabled' do
|
|
137
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
|
138
|
+
with_form_for @user, :company_id, as: :select, full_error: false
|
|
139
|
+
assert_no_select 'span.error'
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
test 'full error can be disabled setting error to false' do
|
|
144
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
|
145
|
+
with_form_for @user, :company_id, as: :select, error: false
|
|
146
|
+
assert_no_select 'span.error'
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# CUSTOM ERRORS
|
|
151
|
+
|
|
152
|
+
test 'input with custom error works' do
|
|
153
|
+
error_text = "Super User Name! can't be blank"
|
|
154
|
+
with_form_for @user, :name, error: error_text
|
|
155
|
+
|
|
156
|
+
assert_select 'span.error', error_text
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
test 'input with error option as true does not use custom error' do
|
|
160
|
+
with_form_for @user, :name, error: true
|
|
161
|
+
|
|
162
|
+
assert_select 'span.error', "can't be blank"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
test 'input with custom error does not generate the error if there is no error on the attribute' do
|
|
166
|
+
with_form_for @user, :active, error: "Super User Active! can't be blank"
|
|
167
|
+
|
|
168
|
+
assert_no_select 'span.error'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
test 'input with custom error works when using full_error component' do
|
|
172
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
|
173
|
+
error_text = "Super User Name! can't be blank"
|
|
174
|
+
with_form_for @user, :name, error: error_text
|
|
175
|
+
|
|
176
|
+
assert_select 'span.error', error_text
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do
|
|
181
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
|
182
|
+
with_form_for @user, :active, error: "Super User Active! can't be blank"
|
|
183
|
+
|
|
184
|
+
assert_no_select 'span.error'
|
|
185
|
+
end
|
|
186
|
+
end
|
|
121
187
|
end
|
|
@@ -43,8 +43,14 @@ class HintTest < ActionView::TestCase
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
test 'hint should be output as html_safe' do
|
|
46
|
-
with_hint_for @user, :name, hint: '<b>Bold</b> and not...'
|
|
46
|
+
with_hint_for @user, :name, hint: '<b>Bold</b> and not...'.html_safe
|
|
47
47
|
assert_select 'span.hint', 'Bold and not...'
|
|
48
|
+
assert_select 'span.hint b', 'Bold'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test 'builder should escape hint text' do
|
|
52
|
+
with_hint_for @user, :name, hint: '<script>alert(1337)</script>'
|
|
53
|
+
assert_select 'span.hint', "<script>alert(1337)</script>"
|
|
48
54
|
end
|
|
49
55
|
|
|
50
56
|
# Without attribute name
|
|
@@ -132,7 +138,7 @@ class HintTest < ActionView::TestCase
|
|
|
132
138
|
test 'hint with custom wrappers works' do
|
|
133
139
|
swap_wrapper do
|
|
134
140
|
with_hint_for @user, :name, hint: "can't be blank"
|
|
135
|
-
assert_select 'div.omg_hint', "can
|
|
141
|
+
assert_select 'div.omg_hint', "can't be blank"
|
|
136
142
|
end
|
|
137
143
|
end
|
|
138
144
|
end
|
|
@@ -88,14 +88,30 @@ class InputFieldTest < ActionView::TestCase
|
|
|
88
88
|
assert_select 'input[min=18]'
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
test 'builder input_field should use pattern component' do
|
|
91
|
+
test 'builder input_field should not use pattern component by default' do
|
|
92
92
|
with_concat_form_for(@other_validating_user) do |f|
|
|
93
93
|
f.input_field :country, as: :string
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
assert_no_select 'input[pattern="\w+"]'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
test 'builder input_field should infer pattern from attributes' do
|
|
100
|
+
with_concat_form_for(@other_validating_user) do |f|
|
|
101
|
+
f.input_field :country, as: :string, pattern: true
|
|
102
|
+
end
|
|
103
|
+
|
|
96
104
|
assert_select 'input[pattern="\w+"]'
|
|
97
105
|
end
|
|
98
106
|
|
|
107
|
+
test 'builder input_field should accept custom patter' do
|
|
108
|
+
with_concat_form_for(@other_validating_user) do |f|
|
|
109
|
+
f.input_field :country, as: :string, pattern: '\d+'
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
assert_select 'input[pattern="\d+"]'
|
|
113
|
+
end
|
|
114
|
+
|
|
99
115
|
test 'builder input_field should use readonly component' do
|
|
100
116
|
with_concat_form_for(@other_validating_user) do |f|
|
|
101
117
|
f.input_field :age, as: :integer, readonly: true
|
|
@@ -122,4 +138,12 @@ class InputFieldTest < ActionView::TestCase
|
|
|
122
138
|
assert_no_select 'select.status[label_method]'
|
|
123
139
|
assert_no_select 'select.status[value_method]'
|
|
124
140
|
end
|
|
141
|
+
|
|
142
|
+
test 'build input_field does not treat "boolean_style" as an HTML attribute' do
|
|
143
|
+
with_concat_form_for(@user) do |f|
|
|
144
|
+
f.input_field :active, boolean_style: :nested
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
assert_no_select 'input.boolean[boolean_style]'
|
|
148
|
+
end
|
|
125
149
|
end
|