simple_form 3.0.4 → 5.0.3
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 +5 -5
- data/CHANGELOG.md +199 -33
- data/MIT-LICENSE +2 -1
- data/README.md +453 -128
- data/lib/generators/simple_form/install_generator.rb +4 -3
- data/lib/generators/simple_form/templates/README +3 -5
- data/lib/generators/simple_form/templates/_form.html.erb +2 -0
- data/lib/generators/simple_form/templates/_form.html.haml +2 -0
- data/lib/generators/simple_form/templates/_form.html.slim +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +47 -16
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +418 -23
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +101 -5
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
- data/lib/simple_form/action_view_extensions/builder.rb +2 -0
- data/lib/simple_form/action_view_extensions/form_helper.rb +10 -3
- data/lib/simple_form/components/errors.rb +39 -6
- data/lib/simple_form/components/hints.rb +3 -2
- data/lib/simple_form/components/html5.rb +16 -5
- data/lib/simple_form/components/label_input.rb +21 -2
- data/lib/simple_form/components/labels.rb +22 -11
- data/lib/simple_form/components/maxlength.rb +9 -5
- data/lib/simple_form/components/min_max.rb +2 -1
- data/lib/simple_form/components/minlength.rb +38 -0
- data/lib/simple_form/components/pattern.rb +2 -1
- data/lib/simple_form/components/placeholders.rb +4 -3
- data/lib/simple_form/components/readonly.rb +2 -1
- data/lib/simple_form/components.rb +2 -0
- data/lib/simple_form/error_notification.rb +1 -0
- data/lib/simple_form/form_builder.rb +220 -89
- 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/helpers.rb +6 -5
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs/base.rb +62 -16
- data/lib/simple_form/inputs/block_input.rb +2 -1
- data/lib/simple_form/inputs/boolean_input.rb +40 -16
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
- data/lib/simple_form/inputs/collection_input.rb +37 -14
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +9 -13
- data/lib/simple_form/inputs/collection_select_input.rb +5 -2
- data/lib/simple_form/inputs/color_input.rb +14 -0
- data/lib/simple_form/inputs/date_time_input.rb +24 -9
- data/lib/simple_form/inputs/file_input.rb +5 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
- data/lib/simple_form/inputs/hidden_input.rb +5 -2
- data/lib/simple_form/inputs/numeric_input.rb +6 -4
- data/lib/simple_form/inputs/password_input.rb +6 -3
- data/lib/simple_form/inputs/priority_input.rb +5 -6
- data/lib/simple_form/inputs/range_input.rb +2 -1
- data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
- data/lib/simple_form/inputs/string_input.rb +7 -4
- data/lib/simple_form/inputs/text_input.rb +6 -3
- data/lib/simple_form/inputs.rb +3 -0
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +8 -0
- data/lib/simple_form/tags.rb +13 -2
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +7 -6
- data/lib/simple_form/wrappers/leaf.rb +29 -0
- data/lib/simple_form/wrappers/many.rb +7 -6
- data/lib/simple_form/wrappers/root.rb +10 -3
- data/lib/simple_form/wrappers/single.rb +7 -4
- data/lib/simple_form/wrappers.rb +2 -0
- data/lib/simple_form.rb +137 -21
- data/test/action_view_extensions/builder_test.rb +64 -45
- data/test/action_view_extensions/form_helper_test.rb +36 -16
- data/test/components/custom_components_test.rb +62 -0
- data/test/components/label_test.rb +70 -41
- data/test/form_builder/association_test.rb +85 -37
- data/test/form_builder/button_test.rb +11 -10
- data/test/form_builder/error_notification_test.rb +2 -1
- data/test/form_builder/error_test.rb +146 -33
- data/test/form_builder/general_test.rb +183 -81
- data/test/form_builder/hint_test.rb +24 -18
- data/test/form_builder/input_field_test.rb +105 -75
- data/test/form_builder/label_test.rb +68 -13
- data/test/form_builder/wrapper_test.rb +197 -22
- data/test/generators/simple_form_generator_test.rb +8 -7
- data/test/inputs/boolean_input_test.rb +97 -6
- data/test/inputs/collection_check_boxes_input_test.rb +117 -25
- data/test/inputs/collection_radio_buttons_input_test.rb +176 -54
- data/test/inputs/collection_select_input_test.rb +189 -77
- data/test/inputs/color_input_test.rb +10 -0
- data/test/inputs/datetime_input_test.rb +121 -50
- data/test/inputs/disabled_test.rb +29 -15
- data/test/inputs/discovery_test.rb +79 -6
- data/test/inputs/file_input_test.rb +3 -2
- data/test/inputs/general_test.rb +23 -22
- data/test/inputs/grouped_collection_select_input_test.rb +54 -17
- data/test/inputs/hidden_input_test.rb +5 -4
- data/test/inputs/numeric_input_test.rb +48 -44
- data/test/inputs/priority_input_test.rb +17 -16
- data/test/inputs/readonly_test.rb +20 -19
- data/test/inputs/required_test.rb +58 -13
- data/test/inputs/rich_text_area_input_test.rb +15 -0
- data/test/inputs/string_input_test.rb +58 -36
- data/test/inputs/text_input_test.rb +20 -7
- data/test/simple_form_test.rb +9 -0
- data/test/support/discovery_inputs.rb +40 -2
- data/test/support/misc_helpers.rb +113 -5
- data/test/support/mock_controller.rb +7 -1
- data/test/support/models.rb +162 -39
- data/test/test_helper.rb +19 -4
- metadata +51 -43
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class PriorityInput < CollectionSelectInput
|
4
|
-
def input
|
5
|
+
def input(wrapper_options = nil)
|
6
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
7
|
+
|
5
8
|
@builder.send(:"#{input_type}_select", attribute_name, input_priority,
|
6
|
-
input_options,
|
9
|
+
input_options, merged_input_options)
|
7
10
|
end
|
8
11
|
|
9
12
|
def input_priority
|
@@ -12,10 +15,6 @@ module SimpleForm
|
|
12
15
|
|
13
16
|
protected
|
14
17
|
|
15
|
-
def has_required?
|
16
|
-
false
|
17
|
-
end
|
18
|
-
|
19
18
|
def skip_include_blank?
|
20
19
|
super || input_priority.present?
|
21
20
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module SimpleForm
|
3
|
+
module Inputs
|
4
|
+
class RichTextAreaInput < Base
|
5
|
+
def input(wrapper_options = nil)
|
6
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
7
|
+
|
8
|
+
@builder.rich_text_area(attribute_name, merged_input_options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,21 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class StringInput < Base
|
4
|
-
enable :placeholder, :maxlength, :pattern
|
5
|
+
enable :placeholder, :maxlength, :minlength, :pattern
|
5
6
|
|
6
|
-
def input
|
7
|
+
def input(wrapper_options = nil)
|
7
8
|
unless string?
|
8
9
|
input_html_classes.unshift("string")
|
9
10
|
input_html_options[:type] ||= input_type if html5?
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
14
|
+
|
15
|
+
@builder.text_field(attribute_name, merged_input_options)
|
13
16
|
end
|
14
17
|
|
15
18
|
private
|
16
19
|
|
17
20
|
def string?
|
18
|
-
input_type == :string
|
21
|
+
input_type == :string || input_type == :citext
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
class TextInput < Base
|
4
|
-
enable :placeholder, :maxlength
|
5
|
+
enable :placeholder, :maxlength, :minlength
|
5
6
|
|
6
|
-
def input
|
7
|
-
|
7
|
+
def input(wrapper_options = nil)
|
8
|
+
merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
|
9
|
+
|
10
|
+
@builder.text_area(attribute_name, merged_input_options)
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
data/lib/simple_form/inputs.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Inputs
|
3
4
|
extend ActiveSupport::Autoload
|
@@ -9,6 +10,7 @@ module SimpleForm
|
|
9
10
|
autoload :CollectionInput
|
10
11
|
autoload :CollectionRadioButtonsInput
|
11
12
|
autoload :CollectionSelectInput
|
13
|
+
autoload :ColorInput
|
12
14
|
autoload :DateTimeInput
|
13
15
|
autoload :FileInput
|
14
16
|
autoload :GroupedCollectionSelectInput
|
@@ -17,6 +19,7 @@ module SimpleForm
|
|
17
19
|
autoload :PasswordInput
|
18
20
|
autoload :PriorityInput
|
19
21
|
autoload :RangeInput
|
22
|
+
autoload :RichTextAreaInput
|
20
23
|
autoload :StringInput
|
21
24
|
autoload :TextInput
|
22
25
|
end
|
data/lib/simple_form/map_type.rb
CHANGED
data/lib/simple_form/railtie.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rails/railtie'
|
2
3
|
|
3
4
|
module SimpleForm
|
4
5
|
class Railtie < Rails::Railtie
|
5
6
|
config.eager_load_namespaces << SimpleForm
|
7
|
+
|
8
|
+
config.after_initialize do
|
9
|
+
unless SimpleForm.configured?
|
10
|
+
warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +
|
11
|
+
' Use `rails generate simple_form:install` to generate the Simple Form configuration.'
|
12
|
+
end
|
13
|
+
end
|
6
14
|
end
|
7
15
|
end
|
data/lib/simple_form/tags.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Tags
|
3
4
|
module CollectionExtensions
|
@@ -15,6 +16,12 @@ module SimpleForm
|
|
15
16
|
|
16
17
|
rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)
|
17
18
|
|
19
|
+
if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
|
20
|
+
label_options = default_html_options.slice(:index, :namespace)
|
21
|
+
label_options['class'] = @options[:item_label_class]
|
22
|
+
rendered_item = @template_object.label(@object_name, sanitize_attribute_name(value), 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
|
@@ -41,7 +48,9 @@ module SimpleForm
|
|
41
48
|
private
|
42
49
|
|
43
50
|
def render_component(builder)
|
44
|
-
|
51
|
+
label_class = "#{@options[:item_label_class]} collection_radio_buttons".strip
|
52
|
+
|
53
|
+
builder.radio_button + builder.label(class: label_class)
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
@@ -55,7 +64,9 @@ module SimpleForm
|
|
55
64
|
private
|
56
65
|
|
57
66
|
def render_component(builder)
|
58
|
-
|
67
|
+
label_class = "#{@options[:item_label_class]} collection_check_boxes".strip
|
68
|
+
|
69
|
+
builder.check_box + builder.label(class: label_class)
|
59
70
|
end
|
60
71
|
end
|
61
72
|
end
|
data/lib/simple_form/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# Provides the builder syntax for components. The builder provides
|
@@ -45,20 +46,20 @@ module SimpleForm
|
|
45
46
|
@components = []
|
46
47
|
end
|
47
48
|
|
48
|
-
def use(name, options=
|
49
|
+
def use(name, options = {})
|
49
50
|
if options && wrapper = options[:wrap_with]
|
50
|
-
@components << Single.new(name, wrapper)
|
51
|
+
@components << Single.new(name, wrapper, options.except(:wrap_with))
|
51
52
|
else
|
52
|
-
@components << name
|
53
|
+
@components << Leaf.new(name, options)
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
def optional(name, options=
|
57
|
+
def optional(name, options = {}, &block)
|
57
58
|
@options[name] = false
|
58
|
-
use(name, options
|
59
|
+
use(name, options)
|
59
60
|
end
|
60
61
|
|
61
|
-
def wrapper(name, options=nil)
|
62
|
+
def wrapper(name, options = nil)
|
62
63
|
if block_given?
|
63
64
|
name, options = nil, name if name.is_a?(Hash)
|
64
65
|
builder = self.class.new(@options)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module SimpleForm
|
3
|
+
module Wrappers
|
4
|
+
class Leaf
|
5
|
+
attr_reader :namespace
|
6
|
+
|
7
|
+
def initialize(namespace, options = {})
|
8
|
+
@namespace = namespace
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def render(input)
|
13
|
+
method = input.method(@namespace)
|
14
|
+
|
15
|
+
if method.arity.zero?
|
16
|
+
ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
|
17
|
+
|
18
|
+
method.call
|
19
|
+
else
|
20
|
+
method.call(@options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def find(name)
|
25
|
+
self if @namespace == name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# A wrapper is an object that holds several components and render them.
|
4
|
-
# A component may
|
5
|
+
# A component may be any object that responds to `render`.
|
5
6
|
# This API allows inputs/components to be easily wrapped, removing the
|
6
7
|
# need to modify the code only to wrap input in an extra tag.
|
7
8
|
#
|
@@ -10,9 +11,8 @@ module SimpleForm
|
|
10
11
|
# on demand on input generation.
|
11
12
|
class Many
|
12
13
|
attr_reader :namespace, :defaults, :components
|
13
|
-
alias :to_sym :namespace
|
14
14
|
|
15
|
-
def initialize(namespace, components, defaults={})
|
15
|
+
def initialize(namespace, components, defaults = {})
|
16
16
|
@namespace = namespace
|
17
17
|
@components = components
|
18
18
|
@defaults = defaults
|
@@ -25,8 +25,8 @@ module SimpleForm
|
|
25
25
|
options = input.options
|
26
26
|
|
27
27
|
components.each do |component|
|
28
|
-
next if options[component] == false
|
29
|
-
rendered = component.
|
28
|
+
next if options[component.namespace] == false
|
29
|
+
rendered = component.render(input)
|
30
30
|
content.safe_concat rendered.to_s if rendered
|
31
31
|
end
|
32
32
|
|
@@ -51,6 +51,7 @@ module SimpleForm
|
|
51
51
|
|
52
52
|
def wrap(input, options, content)
|
53
53
|
return content if options[namespace] == false
|
54
|
+
return if defaults[:unless_blank] && content.empty?
|
54
55
|
|
55
56
|
tag = (namespace && options[:"#{namespace}_tag"]) || @defaults[:tag]
|
56
57
|
return content unless tag
|
@@ -62,7 +63,7 @@ module SimpleForm
|
|
62
63
|
end
|
63
64
|
|
64
65
|
def html_options(options)
|
65
|
-
options[:"#{namespace}_html"] || {}
|
66
|
+
(@defaults[:html] || {}).merge(options[:"#{namespace}_html"] || {})
|
66
67
|
end
|
67
68
|
|
68
69
|
def html_classes(input, options)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# `Root` is the root wrapper for all components. It is special cased to
|
@@ -17,7 +18,7 @@ module SimpleForm
|
|
17
18
|
|
18
19
|
# Provide a fallback if name cannot be found.
|
19
20
|
def find(name)
|
20
|
-
super || SimpleForm::Wrappers::Many.new(name, [name])
|
21
|
+
super || SimpleForm::Wrappers::Many.new(name, [Leaf.new(name)])
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
@@ -27,10 +28,16 @@ module SimpleForm
|
|
27
28
|
css += SimpleForm.additional_classes_for(:wrapper) do
|
28
29
|
input.additional_classes + [input.input_class]
|
29
30
|
end
|
30
|
-
css << (
|
31
|
-
css << (
|
31
|
+
css << html_class(:error_class, options) { input.has_errors? }
|
32
|
+
css << html_class(:hint_class, options) { input.has_hint? }
|
33
|
+
css << html_class(:valid_class, options) { input.valid? }
|
32
34
|
css.compact
|
33
35
|
end
|
36
|
+
|
37
|
+
def html_class(key, options)
|
38
|
+
css = (options[:"wrapper_#{key}"] || @defaults[key])
|
39
|
+
css if css && yield
|
40
|
+
end
|
34
41
|
end
|
35
42
|
end
|
36
43
|
end
|
@@ -1,15 +1,18 @@
|
|
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.
|
4
5
|
class Single < Many
|
5
|
-
def initialize(name, options={})
|
6
|
-
|
6
|
+
def initialize(name, wrapper_options = {}, options = {})
|
7
|
+
@component = Leaf.new(name, options)
|
8
|
+
|
9
|
+
super(name, [@component], wrapper_options)
|
7
10
|
end
|
8
11
|
|
9
12
|
def render(input)
|
10
13
|
options = input.options
|
11
14
|
if options[namespace] != false
|
12
|
-
content =
|
15
|
+
content = @component.render(input)
|
13
16
|
wrap(input, options, content) if content
|
14
17
|
end
|
15
18
|
end
|
@@ -17,7 +20,7 @@ module SimpleForm
|
|
17
20
|
private
|
18
21
|
|
19
22
|
def html_options(options)
|
20
|
-
[
|
23
|
+
%i[label input].include?(namespace) ? {} : super
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
data/lib/simple_form/wrappers.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
autoload :Builder, 'simple_form/wrappers/builder'
|
4
5
|
autoload :Many, 'simple_form/wrappers/many'
|
5
6
|
autoload :Root, 'simple_form/wrappers/root'
|
6
7
|
autoload :Single, 'simple_form/wrappers/single'
|
8
|
+
autoload :Leaf, 'simple_form/wrappers/leaf'
|
7
9
|
end
|
8
10
|
end
|
data/lib/simple_form.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'action_view'
|
3
|
+
require 'action_pack'
|
2
4
|
require 'simple_form/action_view_extensions/form_helper'
|
3
5
|
require 'simple_form/action_view_extensions/builder'
|
4
6
|
require 'active_support/core_ext/hash/slice'
|
@@ -24,6 +26,35 @@ module SimpleForm
|
|
24
26
|
SimpleForm::Components.eager_load!
|
25
27
|
end
|
26
28
|
|
29
|
+
CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN
|
30
|
+
%{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:
|
31
|
+
|
32
|
+
def %{name}
|
33
|
+
|
34
|
+
to
|
35
|
+
|
36
|
+
def %{name}(wrapper_options)
|
37
|
+
|
38
|
+
See https://github.com/heartcombo/simple_form/pull/997 for more information.
|
39
|
+
WARN
|
40
|
+
|
41
|
+
FILE_METHODS_DEPRECATION_WARN = <<-WARN
|
42
|
+
[SIMPLE_FORM] SimpleForm.file_methods is deprecated and has no effect.
|
43
|
+
|
44
|
+
Since version 5, Simple Form now supports automatically discover of file inputs for the following Gems: activestorage, carrierwave, paperclip, refile and shrine.
|
45
|
+
If you are using a custom method that is not from one of the supported Gems, please change your forms to pass the input type explicitly:
|
46
|
+
|
47
|
+
<%= form.input :avatar, as: :file %>
|
48
|
+
|
49
|
+
See http://blog.plataformatec.com.br/2019/09/incorrect-access-control-in-simple-form-cve-2019-16676 for more information.
|
50
|
+
WARN
|
51
|
+
|
52
|
+
@@configured = false
|
53
|
+
|
54
|
+
def self.configured? #:nodoc:
|
55
|
+
@@configured
|
56
|
+
end
|
57
|
+
|
27
58
|
## CONFIGURATION OPTIONS
|
28
59
|
|
29
60
|
# Method used to tidy up errors.
|
@@ -40,11 +71,11 @@ module SimpleForm
|
|
40
71
|
|
41
72
|
# Series of attemps to detect a default label method for collection.
|
42
73
|
mattr_accessor :collection_label_methods
|
43
|
-
@@collection_label_methods = [
|
74
|
+
@@collection_label_methods = %i[to_label name title to_s]
|
44
75
|
|
45
76
|
# Series of attemps to detect a default value method for collection.
|
46
77
|
mattr_accessor :collection_value_methods
|
47
|
-
@@collection_value_methods = [
|
78
|
+
@@collection_value_methods = %i[id to_s]
|
48
79
|
|
49
80
|
# You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
|
50
81
|
mattr_accessor :collection_wrapper_tag
|
@@ -66,7 +97,7 @@ module SimpleForm
|
|
66
97
|
|
67
98
|
# How the label text should be generated altogether with the required text.
|
68
99
|
mattr_accessor :label_text
|
69
|
-
@@label_text =
|
100
|
+
@@label_text = ->(label, required, explicit_label) { "#{required} #{label}" }
|
70
101
|
|
71
102
|
# You can define the class to be used on all labels. Defaults to none.
|
72
103
|
mattr_accessor :label_class
|
@@ -78,13 +109,19 @@ module SimpleForm
|
|
78
109
|
mattr_accessor :boolean_style
|
79
110
|
@@boolean_style = :inline
|
80
111
|
|
81
|
-
# You can define the class to be used on all forms. Default is
|
82
|
-
|
112
|
+
# DEPRECATED: You can define the class to be used on all forms. Default is
|
113
|
+
# simple_form.
|
114
|
+
mattr_reader :form_class
|
83
115
|
@@form_class = :simple_form
|
84
116
|
|
117
|
+
# You can define the default class to be used on all forms. Can be overriden
|
118
|
+
# with `html: { :class }`. Defaults to none.
|
119
|
+
mattr_accessor :default_form_class
|
120
|
+
@@default_form_class = nil
|
121
|
+
|
85
122
|
# You can define which elements should obtain additional classes.
|
86
123
|
mattr_accessor :generate_additional_classes_for
|
87
|
-
@@generate_additional_classes_for = [
|
124
|
+
@@generate_additional_classes_for = %i[wrapper label input]
|
88
125
|
|
89
126
|
# Whether attributes are required by default or not.
|
90
127
|
mattr_accessor :required_by_default
|
@@ -94,10 +131,6 @@ module SimpleForm
|
|
94
131
|
mattr_accessor :browser_validations
|
95
132
|
@@browser_validations = true
|
96
133
|
|
97
|
-
# Collection of methods to detect if a file type was given.
|
98
|
-
mattr_accessor :file_methods
|
99
|
-
@@file_methods = [:mounted_as, :file?, :public_filename]
|
100
|
-
|
101
134
|
# Custom mappings for input types. This should be a hash containing a regexp
|
102
135
|
# to match as key, and the input type that will be used when the field name
|
103
136
|
# matches the regexp as value, such as { /count/ => :integer }.
|
@@ -107,9 +140,19 @@ module SimpleForm
|
|
107
140
|
# Custom wrappers for input types. This should be a hash containing an input
|
108
141
|
# type as key and the wrapper that will be used for all inputs with specified type.
|
109
142
|
# e.g { string: :string_wrapper, boolean: :boolean_wrapper }
|
143
|
+
# You can also set a wrapper mapping per form basis.
|
144
|
+
# e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox })
|
110
145
|
mattr_accessor :wrapper_mappings
|
111
146
|
@@wrapper_mappings = nil
|
112
147
|
|
148
|
+
# Namespaces where SimpleForm should look for custom input classes that override
|
149
|
+
# default inputs. Namespaces are given as string to allow lazy loading inputs.
|
150
|
+
# e.g. config.custom_inputs_namespaces << "CustomInputs"
|
151
|
+
# will try to find CustomInputs::NumericInput when an :integer
|
152
|
+
# field is called.
|
153
|
+
mattr_accessor :custom_inputs_namespaces
|
154
|
+
@@custom_inputs_namespaces = []
|
155
|
+
|
113
156
|
# Default priority for time_zone inputs.
|
114
157
|
mattr_accessor :time_zone_priority
|
115
158
|
@@time_zone_priority = nil
|
@@ -118,10 +161,6 @@ module SimpleForm
|
|
118
161
|
mattr_accessor :country_priority
|
119
162
|
@@country_priority = nil
|
120
163
|
|
121
|
-
# DEPRECATED: Maximum size allowed for inputs.
|
122
|
-
mattr_accessor :default_input_size
|
123
|
-
@@default_input_size = nil
|
124
|
-
|
125
164
|
# When off, do not use translations in labels. Disabling translation in
|
126
165
|
# hints and placeholders can be done manually in the wrapper API.
|
127
166
|
mattr_accessor :translate_labels
|
@@ -133,7 +172,7 @@ module SimpleForm
|
|
133
172
|
|
134
173
|
# Cache SimpleForm inputs discovery.
|
135
174
|
mattr_accessor :cache_discovery
|
136
|
-
@@cache_discovery = defined?(Rails) && !Rails.env.development?
|
175
|
+
@@cache_discovery = defined?(Rails.env) && !Rails.env.development?
|
137
176
|
|
138
177
|
# Adds a class to each generated button, mostly for compatiblity.
|
139
178
|
mattr_accessor :button_class
|
@@ -151,15 +190,32 @@ module SimpleForm
|
|
151
190
|
mattr_accessor :input_class
|
152
191
|
@@input_class = nil
|
153
192
|
|
193
|
+
# Defines if an input wrapper class should be included or not
|
194
|
+
mattr_accessor :include_default_input_wrapper_class
|
195
|
+
@@include_default_input_wrapper_class = true
|
196
|
+
|
197
|
+
# Define the default class of the input wrapper of the boolean input.
|
198
|
+
mattr_accessor :boolean_label_class
|
199
|
+
@@boolean_label_class = 'checkbox'
|
200
|
+
|
154
201
|
## WRAPPER CONFIGURATION
|
155
202
|
# The default wrapper to be used by the FormBuilder.
|
156
203
|
mattr_accessor :default_wrapper
|
157
204
|
@@default_wrapper = :default
|
158
|
-
@@wrappers = {}
|
205
|
+
@@wrappers = {} #:nodoc:
|
206
|
+
|
207
|
+
mattr_accessor :i18n_scope
|
208
|
+
@@i18n_scope = 'simple_form'
|
209
|
+
|
210
|
+
mattr_accessor :input_field_error_class
|
211
|
+
@@input_field_error_class = nil
|
212
|
+
|
213
|
+
mattr_accessor :input_field_valid_class
|
214
|
+
@@input_field_valid_class = nil
|
159
215
|
|
160
216
|
# Retrieves a given wrapper
|
161
217
|
def self.wrapper(name)
|
162
|
-
@@wrappers[name.
|
218
|
+
@@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
|
163
219
|
end
|
164
220
|
|
165
221
|
# Raised when fails to find a given wrapper name
|
@@ -172,25 +228,26 @@ module SimpleForm
|
|
172
228
|
if block_given?
|
173
229
|
options = args.extract_options!
|
174
230
|
name = args.first || :default
|
175
|
-
@@wrappers[name.
|
231
|
+
@@wrappers[name.to_s] = build(options, &block)
|
176
232
|
else
|
177
233
|
@@wrappers
|
178
234
|
end
|
179
235
|
end
|
180
236
|
|
181
237
|
# Builds a new wrapper using SimpleForm::Wrappers::Builder.
|
182
|
-
def self.build(options={})
|
238
|
+
def self.build(options = {})
|
183
239
|
options[:tag] = :div if options[:tag].nil?
|
184
240
|
builder = SimpleForm::Wrappers::Builder.new(options)
|
185
241
|
yield builder
|
186
242
|
SimpleForm::Wrappers::Root.new(builder.to_a, options)
|
187
243
|
end
|
188
244
|
|
189
|
-
wrappers class: :input, hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
245
|
+
wrappers class: :input, hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|
|
190
246
|
b.use :html5
|
191
247
|
|
192
248
|
b.use :min_max
|
193
249
|
b.use :maxlength
|
250
|
+
b.use :minlength
|
194
251
|
b.use :placeholder
|
195
252
|
b.optional :pattern
|
196
253
|
b.optional :readonly
|
@@ -210,11 +267,70 @@ module SimpleForm
|
|
210
267
|
ActiveSupport::Deprecation.warn "[SIMPLE_FORM] SimpleForm.default_input_size= is deprecated and has no effect", caller
|
211
268
|
end
|
212
269
|
|
213
|
-
|
270
|
+
def self.form_class=(value)
|
271
|
+
ActiveSupport::Deprecation.warn "[SIMPLE_FORM] SimpleForm.form_class= is deprecated and will be removed in 4.x. Use SimpleForm.default_form_class= instead", caller
|
272
|
+
@@form_class = value
|
273
|
+
end
|
274
|
+
|
275
|
+
def self.file_methods=(file_methods)
|
276
|
+
ActiveSupport::Deprecation.warn(FILE_METHODS_DEPRECATION_WARN, caller)
|
277
|
+
@@file_methods = file_methods
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.file_methods
|
281
|
+
ActiveSupport::Deprecation.warn(FILE_METHODS_DEPRECATION_WARN, caller)
|
282
|
+
@@file_methods
|
283
|
+
end
|
284
|
+
|
285
|
+
# Default way to setup Simple Form. Run rails generate simple_form:install
|
214
286
|
# to create a fresh initializer with all configuration values.
|
215
287
|
def self.setup
|
288
|
+
@@configured = true
|
216
289
|
yield self
|
217
290
|
end
|
291
|
+
|
292
|
+
# Includes a component to be used by Simple Form. Methods defined in a
|
293
|
+
# component will be exposed to be used in the wrapper as Simple::Components
|
294
|
+
#
|
295
|
+
# Examples
|
296
|
+
#
|
297
|
+
# # The application needs to tell where the components will be.
|
298
|
+
# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
|
299
|
+
#
|
300
|
+
# # Create a custom component in the path specified above.
|
301
|
+
# # lib/components/input_group_component.rb
|
302
|
+
# module InputGroupComponent
|
303
|
+
# def prepend
|
304
|
+
# ...
|
305
|
+
# end
|
306
|
+
#
|
307
|
+
# def append
|
308
|
+
# ...
|
309
|
+
# end
|
310
|
+
# end
|
311
|
+
#
|
312
|
+
# SimpleForm.setup do |config|
|
313
|
+
# # Create a wrapper using the custom component.
|
314
|
+
# config.wrappers :input_group, tag: :div, error_class: :error do |b|
|
315
|
+
# b.use :label
|
316
|
+
# b.optional :prepend
|
317
|
+
# b.use :input
|
318
|
+
# b.use :append
|
319
|
+
# end
|
320
|
+
# end
|
321
|
+
#
|
322
|
+
# # Using the custom component in the form.
|
323
|
+
# <%= simple_form_for @blog, wrapper: input_group do |f| %>
|
324
|
+
# <%= f.input :title, prepend: true %>
|
325
|
+
# <% end %>
|
326
|
+
#
|
327
|
+
def self.include_component(component)
|
328
|
+
if Module === component
|
329
|
+
SimpleForm::Inputs::Base.include(component)
|
330
|
+
else
|
331
|
+
raise TypeError, "SimpleForm.include_component expects a module but got: #{component.class}"
|
332
|
+
end
|
333
|
+
end
|
218
334
|
end
|
219
335
|
|
220
336
|
require 'simple_form/railtie' if defined?(Rails)
|