simple_form 1.5.2 → 2.0.0.rc
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.
- data/CHANGELOG.md +224 -0
- data/MIT-LICENSE +1 -1
- data/README.md +817 -0
- data/lib/generators/simple_form/install_generator.rb +15 -1
- data/lib/generators/simple_form/templates/README +12 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +173 -0
- data/lib/simple_form.rb +109 -43
- data/lib/simple_form/action_view_extensions/builder.rb +158 -53
- data/lib/simple_form/action_view_extensions/form_helper.rb +29 -22
- data/lib/simple_form/components.rb +11 -1
- data/lib/simple_form/components/errors.rb +6 -24
- data/lib/simple_form/components/hints.rb +7 -21
- data/lib/simple_form/components/html5.rb +26 -0
- data/lib/simple_form/components/labels.rb +15 -13
- data/lib/simple_form/components/maxlength.rb +41 -0
- data/lib/simple_form/components/min_max.rb +49 -0
- data/lib/simple_form/components/pattern.rb +34 -0
- data/lib/simple_form/components/placeholders.rb +5 -17
- data/lib/simple_form/components/readonly.rb +22 -0
- data/lib/simple_form/core_ext/hash.rb +16 -0
- data/lib/simple_form/error_notification.rb +8 -1
- data/lib/simple_form/form_builder.rb +86 -22
- data/lib/simple_form/helpers.rb +7 -4
- data/lib/simple_form/helpers/autofocus.rb +11 -0
- data/lib/simple_form/helpers/disabled.rb +15 -0
- data/lib/simple_form/helpers/readonly.rb +15 -0
- data/lib/simple_form/helpers/required.rb +7 -10
- data/lib/simple_form/helpers/validators.rb +4 -4
- data/lib/simple_form/inputs.rb +17 -13
- data/lib/simple_form/inputs/base.rb +50 -81
- data/lib/simple_form/inputs/boolean_input.rb +43 -4
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +21 -0
- data/lib/simple_form/inputs/collection_input.rb +27 -13
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +69 -0
- data/lib/simple_form/inputs/collection_select_input.rb +14 -0
- data/lib/simple_form/inputs/date_time_input.rb +2 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +41 -0
- data/lib/simple_form/inputs/hidden_input.rb +3 -6
- data/lib/simple_form/inputs/numeric_input.rb +3 -51
- data/lib/simple_form/inputs/password_input.rb +1 -2
- data/lib/simple_form/inputs/priority_input.rb +2 -2
- data/lib/simple_form/inputs/range_input.rb +1 -3
- data/lib/simple_form/inputs/string_input.rb +6 -8
- data/lib/simple_form/inputs/text_input.rb +1 -2
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers.rb +8 -0
- data/lib/simple_form/wrappers/builder.rb +75 -0
- data/lib/simple_form/wrappers/many.rb +68 -0
- data/lib/simple_form/wrappers/root.rb +34 -0
- data/lib/simple_form/wrappers/single.rb +18 -0
- data/test/action_view_extensions/builder_test.rb +195 -100
- data/test/action_view_extensions/form_helper_test.rb +24 -2
- data/test/components/label_test.rb +20 -5
- data/test/form_builder/association_test.rb +167 -0
- data/test/form_builder/button_test.rb +28 -0
- data/test/{error_notification_test.rb → form_builder/error_notification_test.rb} +2 -1
- data/test/form_builder/error_test.rb +101 -0
- data/test/form_builder/general_test.rb +348 -0
- data/test/form_builder/hint_test.rb +115 -0
- data/test/form_builder/input_field_test.rb +51 -0
- data/test/form_builder/label_test.rb +51 -0
- data/test/form_builder/wrapper_test.rb +140 -0
- data/test/generators/simple_form_generator_test.rb +32 -0
- data/test/inputs/boolean_input_test.rb +91 -0
- data/test/inputs/collection_check_boxes_input_test.rb +224 -0
- data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
- data/test/inputs/collection_select_input_test.rb +241 -0
- data/test/inputs/datetime_input_test.rb +85 -0
- data/test/inputs/disabled_test.rb +38 -0
- data/test/inputs/discovery_test.rb +61 -0
- data/test/inputs/file_input_test.rb +16 -0
- data/test/inputs/general_test.rb +69 -0
- data/test/inputs/grouped_collection_select_input_test.rb +109 -0
- data/test/inputs/hidden_input_test.rb +30 -0
- data/test/inputs/numeric_input_test.rb +167 -0
- data/test/inputs/priority_input_test.rb +43 -0
- data/test/inputs/readonly_test.rb +61 -0
- data/test/inputs/required_test.rb +113 -0
- data/test/inputs/string_input_test.rb +140 -0
- data/test/inputs/text_input_test.rb +24 -0
- data/test/{discovery_inputs.rb → support/discovery_inputs.rb} +0 -0
- data/test/support/misc_helpers.rb +48 -6
- data/test/support/mock_controller.rb +2 -2
- data/test/support/models.rb +20 -5
- data/test/test_helper.rb +5 -8
- metadata +123 -98
- data/.gitignore +0 -3
- data/.gitmodules +0 -3
- data/.travis.yml +0 -15
- data/CHANGELOG.rdoc +0 -159
- data/Gemfile +0 -9
- data/README.rdoc +0 -466
- data/Rakefile +0 -27
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +0 -93
- data/lib/simple_form/components/wrapper.rb +0 -38
- data/lib/simple_form/helpers/has_errors.rb +0 -15
- data/lib/simple_form/helpers/maxlength.rb +0 -24
- data/lib/simple_form/helpers/pattern.rb +0 -28
- data/simple_form.gemspec +0 -25
- data/test/components/error_test.rb +0 -56
- data/test/components/hint_test.rb +0 -74
- data/test/components/wrapper_test.rb +0 -63
- data/test/custom_components.rb +0 -7
- data/test/form_builder_test.rb +0 -930
- data/test/inputs_test.rb +0 -995
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
module SimpleForm
|
|
2
2
|
module Inputs
|
|
3
3
|
class StringInput < Base
|
|
4
|
-
enable :placeholder
|
|
4
|
+
enable :placeholder, :maxlength, :pattern
|
|
5
5
|
|
|
6
6
|
def input
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
unless string?
|
|
8
|
+
input_html_classes.unshift("string")
|
|
9
|
+
input_html_options[:type] ||= input_type if html5?
|
|
10
|
+
end
|
|
11
|
+
|
|
10
12
|
add_size!
|
|
11
13
|
@builder.text_field(attribute_name, input_html_options)
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
def input_html_classes
|
|
15
|
-
string? ? super : super.unshift("string")
|
|
16
|
-
end
|
|
17
|
-
|
|
18
16
|
private
|
|
19
17
|
|
|
20
18
|
def string?
|
data/lib/simple_form/version.rb
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module Wrappers
|
|
3
|
+
# Provides the builder syntax for components. The builder provides
|
|
4
|
+
# only one method (called `use`) and it allows the following invocations:
|
|
5
|
+
#
|
|
6
|
+
# config.wrappers do |b|
|
|
7
|
+
# # Use a single component
|
|
8
|
+
# b.use :placeholder
|
|
9
|
+
#
|
|
10
|
+
# # Use a component with specific wrapper options
|
|
11
|
+
# b.use :error, :tag => "span", :class => "error"
|
|
12
|
+
#
|
|
13
|
+
# # Use a set of components by wrapping them in a tag+class.
|
|
14
|
+
# b.use :tag => "div", :class => "another" do |ba|
|
|
15
|
+
# ba.use :label
|
|
16
|
+
# ba.use :input
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# # Use a set of components by wrapping them in a tag+class.
|
|
20
|
+
# # This wrapper is identified by :label_input, which means it can
|
|
21
|
+
# # be turned off on demand with `f.input :name, :label_input => false`
|
|
22
|
+
# b.use :label_input, :tag => "div", :class => "another" do |ba|
|
|
23
|
+
# ba.use :label
|
|
24
|
+
# ba.use :input
|
|
25
|
+
# end
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# The builder also accepts default options at the root level. This is usually
|
|
29
|
+
# used if you want a component to be disabled by default:
|
|
30
|
+
#
|
|
31
|
+
# config.wrappers :hint => false do |b|
|
|
32
|
+
# b.use :hint
|
|
33
|
+
# b.use :label_input
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# In the example above, hint defaults to false, which means it won't automatically
|
|
37
|
+
# do the lookup anymore. It will only be triggered when :hint is explicitly set.
|
|
38
|
+
class Builder
|
|
39
|
+
def initialize(options)
|
|
40
|
+
@options = options
|
|
41
|
+
@components = []
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def use(name, options=nil, &block)
|
|
45
|
+
add(name, options, &block)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def optional(name, options=nil, &block)
|
|
49
|
+
@options[name] = false
|
|
50
|
+
add(name, options, &block)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_a
|
|
54
|
+
@components
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def add(name, options)
|
|
60
|
+
if block_given?
|
|
61
|
+
name, options = nil, name if name.is_a?(Hash)
|
|
62
|
+
builder = self.class.new(@options)
|
|
63
|
+
options ||= {}
|
|
64
|
+
options[:tag] = :div if options[:tag].nil?
|
|
65
|
+
yield builder
|
|
66
|
+
@components << Many.new(name, builder.to_a, options)
|
|
67
|
+
elsif options
|
|
68
|
+
@components << Single.new(name, options)
|
|
69
|
+
else
|
|
70
|
+
@components << name
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module Wrappers
|
|
3
|
+
# A wrapper is an object that holds several components and render them.
|
|
4
|
+
# A component may either be a symbol or any object that responds to `render`.
|
|
5
|
+
# This API allows inputs/components to be easily wrapped, removing the
|
|
6
|
+
# need to modify the code only to wrap input in an extra tag.
|
|
7
|
+
#
|
|
8
|
+
# `Many` represents a wrapper around several components at the same time.
|
|
9
|
+
# It may optionally receive a namespace, allowing it to be configured
|
|
10
|
+
# on demand on input generation.
|
|
11
|
+
class Many
|
|
12
|
+
attr_reader :namespace, :defaults, :components
|
|
13
|
+
alias :to_sym :namespace
|
|
14
|
+
|
|
15
|
+
def initialize(namespace, components, defaults={})
|
|
16
|
+
@namespace = namespace
|
|
17
|
+
@components = components
|
|
18
|
+
@defaults = defaults
|
|
19
|
+
@defaults[:class] = Array.wrap(@defaults[:class])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def render(input)
|
|
23
|
+
content = "".html_safe
|
|
24
|
+
options = input.options
|
|
25
|
+
|
|
26
|
+
components.each do |component|
|
|
27
|
+
next if options[component] == false
|
|
28
|
+
rendered = component.respond_to?(:render) ? component.render(input) : input.send(component)
|
|
29
|
+
content.safe_concat rendered.to_s if rendered
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
wrap(input, options, content)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def find(name)
|
|
36
|
+
return self if namespace == name
|
|
37
|
+
|
|
38
|
+
@components.each do |c|
|
|
39
|
+
if c.is_a?(Symbol)
|
|
40
|
+
return nil if c == namespace
|
|
41
|
+
elsif value = c.find(name)
|
|
42
|
+
return value
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def wrap(input, options, content)
|
|
52
|
+
return content if options[namespace] == false
|
|
53
|
+
|
|
54
|
+
tag = (namespace && options[:"#{namespace}_tag"]) || @defaults[:tag]
|
|
55
|
+
return content unless tag
|
|
56
|
+
|
|
57
|
+
klass = html_classes(input, options)
|
|
58
|
+
opts = options[:"#{namespace}_html"] || {}
|
|
59
|
+
opts[:class] = (klass << opts[:class]).join(' ').strip unless klass.empty?
|
|
60
|
+
input.template.content_tag(tag, content, opts)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def html_classes(input, options)
|
|
64
|
+
@defaults[:class].dup
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module Wrappers
|
|
3
|
+
# `Root` is the root wrapper for all components. It is special cased to
|
|
4
|
+
# always have a namespace and to add special html classes.
|
|
5
|
+
class Root < Many
|
|
6
|
+
attr_reader :options
|
|
7
|
+
|
|
8
|
+
def initialize(*args)
|
|
9
|
+
super(:wrapper, *args)
|
|
10
|
+
@options = @defaults.except(:tag, :class, :error_class, :hint_class)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def render(input)
|
|
14
|
+
input.options.reverse_merge!(@options)
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Provide a fallback if name cannot be found.
|
|
19
|
+
def find(name)
|
|
20
|
+
super || SimpleForm::Wrappers::Many.new(name, [name])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def html_classes(input, options)
|
|
26
|
+
css = options[:wrapper_class] ? Array.wrap(options[:wrapper_class]) : @defaults[:class]
|
|
27
|
+
css += input.html_classes
|
|
28
|
+
css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
|
|
29
|
+
css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
|
|
30
|
+
css
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module SimpleForm
|
|
2
|
+
module Wrappers
|
|
3
|
+
# `Single` is an optimization for a wrapper that has only one component.
|
|
4
|
+
class Single < Many
|
|
5
|
+
def initialize(name, options={})
|
|
6
|
+
super(name, [name], options)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def render(input)
|
|
10
|
+
options = input.options
|
|
11
|
+
if options[namespace] != false
|
|
12
|
+
content = input.send(namespace)
|
|
13
|
+
wrap(input, options, content) if content
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -8,48 +8,48 @@ class BuilderTest < ActionView::TestCase
|
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def
|
|
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
|
-
f.
|
|
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={})
|
|
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
|
-
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options
|
|
19
|
+
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# COLLECTION RADIO
|
|
24
24
|
test 'collection radio accepts a collection and generate inputs from value method' do
|
|
25
|
-
|
|
25
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
|
|
26
26
|
|
|
27
27
|
assert_select 'form input[type=radio][value=true]#user_active_true'
|
|
28
28
|
assert_select 'form input[type=radio][value=false]#user_active_false'
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
test 'collection radio accepts a collection and generate inputs from label method' do
|
|
32
|
-
|
|
32
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
|
|
33
33
|
|
|
34
|
-
assert_select 'form label.
|
|
35
|
-
assert_select 'form label.
|
|
34
|
+
assert_select 'form label.collection_radio_buttons[for=user_active_true]', 'true'
|
|
35
|
+
assert_select 'form label.collection_radio_buttons[for=user_active_false]', 'false'
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
test 'collection radio handles camelized collection values for labels correctly' do
|
|
39
|
-
|
|
39
|
+
with_collection_radio_buttons @user, :active, ['Yes', 'No'], :to_s, :to_s
|
|
40
40
|
|
|
41
|
-
assert_select 'form label.
|
|
42
|
-
assert_select 'form label.
|
|
41
|
+
assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'
|
|
42
|
+
assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
test 'colection radio should sanitize collection values for labels correctly' do
|
|
46
|
-
|
|
47
|
-
assert_select 'label.
|
|
48
|
-
assert_select 'label.
|
|
46
|
+
with_collection_radio_buttons @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
|
|
47
|
+
assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
|
|
48
|
+
assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
test 'collection radio accepts checked item' do
|
|
52
|
-
|
|
52
|
+
with_collection_radio_buttons @user, :active, [[1, true], [0, false]], :last, :first, :checked => true
|
|
53
53
|
|
|
54
54
|
assert_select 'form input[type=radio][value=true][checked=checked]'
|
|
55
55
|
assert_no_select 'form input[type=radio][value=false][checked=checked]'
|
|
@@ -57,7 +57,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
57
57
|
|
|
58
58
|
test 'collection radio accepts multiple disabled items' do
|
|
59
59
|
collection = [[1, true], [0, false], [2, 'other']]
|
|
60
|
-
|
|
60
|
+
with_collection_radio_buttons @user, :active, collection, :last, :first, :disabled => [true, false]
|
|
61
61
|
|
|
62
62
|
assert_select 'form input[type=radio][value=true][disabled=disabled]'
|
|
63
63
|
assert_select 'form input[type=radio][value=false][disabled=disabled]'
|
|
@@ -66,7 +66,7 @@ class BuilderTest < ActionView::TestCase
|
|
|
66
66
|
|
|
67
67
|
test 'collection radio accepts single disable item' do
|
|
68
68
|
collection = [[1, true], [0, false]]
|
|
69
|
-
|
|
69
|
+
with_collection_radio_buttons @user, :active, collection, :last, :first, :disabled => true
|
|
70
70
|
|
|
71
71
|
assert_select 'form input[type=radio][value=true][disabled=disabled]'
|
|
72
72
|
assert_no_select 'form input[type=radio][value=false][disabled=disabled]'
|
|
@@ -74,105 +74,143 @@ class BuilderTest < ActionView::TestCase
|
|
|
74
74
|
|
|
75
75
|
test 'collection radio accepts html options as input' do
|
|
76
76
|
collection = [[1, true], [0, false]]
|
|
77
|
-
|
|
77
|
+
with_collection_radio_buttons @user, :active, collection, :last, :first, {}, :class => 'special-radio'
|
|
78
78
|
|
|
79
|
-
assert_select 'form input[type=radio][value=true].radio#user_active_true'
|
|
80
|
-
assert_select 'form input[type=radio][value=false].radio#user_active_false'
|
|
79
|
+
assert_select 'form input[type=radio][value=true].special-radio#user_active_true'
|
|
80
|
+
assert_select 'form input[type=radio][value=false].special-radio#user_active_false'
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
-
test 'collection radio wraps the collection in the
|
|
84
|
-
|
|
85
|
-
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
83
|
+
test 'collection radio wraps the collection in the given collection wrapper tag' do
|
|
84
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
assert_select 'form ul input[type=radio][value=false]#user_active_false'
|
|
89
|
-
end
|
|
86
|
+
assert_select 'form ul input[type=radio]', :count => 2
|
|
90
87
|
end
|
|
91
88
|
|
|
92
|
-
test 'collection radio
|
|
93
|
-
|
|
89
|
+
test 'collection radio does not render any wrapper tag by default' do
|
|
90
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
|
|
94
91
|
|
|
95
|
-
assert_select 'form
|
|
96
|
-
|
|
92
|
+
assert_select 'form input[type=radio]', :count => 2
|
|
93
|
+
assert_no_select 'form ul'
|
|
97
94
|
end
|
|
98
95
|
|
|
99
|
-
test 'collection radio does not wrap the collection
|
|
100
|
-
|
|
101
|
-
with_collection_radio @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
|
|
96
|
+
test 'collection radio does not wrap the collection when given falsy values' do
|
|
97
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
|
|
102
98
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
end
|
|
99
|
+
assert_select 'form input[type=radio]', :count => 2
|
|
100
|
+
assert_no_select 'form ul'
|
|
106
101
|
end
|
|
107
102
|
|
|
108
|
-
test 'collection radio
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
test 'collection radio uses the given class for collection wrapper tag' do
|
|
104
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
|
|
105
|
+
:collection_wrapper_tag => :ul, :collection_wrapper_class => "items-list"
|
|
111
106
|
|
|
112
|
-
|
|
113
|
-
assert_no_select 'form ul'
|
|
114
|
-
end
|
|
107
|
+
assert_select 'form ul.items-list input[type=radio]', :count => 2
|
|
115
108
|
end
|
|
116
109
|
|
|
117
|
-
test 'collection radio
|
|
118
|
-
|
|
110
|
+
test 'collection radio uses no class for collection wrapper tag when no wrapper tag is given' do
|
|
111
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
|
|
112
|
+
:collection_wrapper_class => "items-list"
|
|
119
113
|
|
|
114
|
+
assert_select 'form input[type=radio]', :count => 2
|
|
120
115
|
assert_no_select 'form ul'
|
|
116
|
+
assert_no_select '.items-list'
|
|
121
117
|
end
|
|
122
118
|
|
|
123
|
-
test 'collection radio
|
|
124
|
-
|
|
125
|
-
with_collection_radio @user, :active, [true, false], :to_s, :to_s
|
|
119
|
+
test 'collection radio uses no class for collection wrapper tag by default' do
|
|
120
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
126
121
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
end
|
|
122
|
+
assert_select 'form ul'
|
|
123
|
+
assert_no_select 'form ul[class]'
|
|
130
124
|
end
|
|
131
125
|
|
|
132
|
-
test 'collection radio
|
|
133
|
-
|
|
126
|
+
test 'collection radio wrap items in a span tag by default' do
|
|
127
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
|
|
134
128
|
|
|
135
|
-
assert_select 'form
|
|
136
|
-
assert_select 'form
|
|
129
|
+
assert_select 'form span input[type=radio][value=true]#user_active_true + label'
|
|
130
|
+
assert_select 'form span input[type=radio][value=false]#user_active_false + label'
|
|
137
131
|
end
|
|
138
132
|
|
|
139
|
-
test 'collection radio
|
|
140
|
-
|
|
133
|
+
test 'collection radio wraps each item in the given item wrapper tag' do
|
|
134
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
|
|
141
135
|
|
|
142
|
-
|
|
143
|
-
assert_no_select 'form span input[type=radio][value=false]#user_active_false'
|
|
136
|
+
assert_select 'form li input[type=radio]', :count => 2
|
|
144
137
|
end
|
|
145
138
|
|
|
146
|
-
test 'collection radio does not wrap each
|
|
147
|
-
|
|
139
|
+
test 'collection radio does not wrap each item when given explicitly falsy value' do
|
|
140
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => false
|
|
148
141
|
|
|
149
|
-
|
|
150
|
-
assert_no_select 'form span input[type=radio]
|
|
142
|
+
assert_select 'form input[type=radio]'
|
|
143
|
+
assert_no_select 'form span input[type=radio]'
|
|
151
144
|
end
|
|
152
145
|
|
|
153
|
-
test 'collection radio
|
|
154
|
-
|
|
146
|
+
test 'collection radio uses the given class for item wrapper tag' do
|
|
147
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
|
|
148
|
+
:item_wrapper_tag => :li, :item_wrapper_class => "inline"
|
|
155
149
|
|
|
156
|
-
assert_select
|
|
157
|
-
|
|
150
|
+
assert_select "form li.inline input[type=radio]", :count => 2
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
test 'collection radio uses no class for item wrapper tag when no wrapper tag is given' do
|
|
154
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
|
|
155
|
+
:item_wrapper_tag => nil, :item_wrapper_class => "inline"
|
|
156
|
+
|
|
157
|
+
assert_select 'form input[type=radio]', :count => 2
|
|
158
|
+
assert_no_select 'form li'
|
|
159
|
+
assert_no_select '.inline'
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
test 'collection radio uses no class for item wrapper tag by default' do
|
|
163
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
|
|
164
|
+
:item_wrapper_tag => :li
|
|
165
|
+
|
|
166
|
+
assert_select "form li", :count => 2
|
|
167
|
+
assert_no_select "form li[class]"
|
|
158
168
|
end
|
|
159
169
|
|
|
160
170
|
test 'collection radio does not wrap input inside the label' do
|
|
161
|
-
|
|
171
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
|
|
162
172
|
|
|
173
|
+
assert_select 'form input[type=radio] + label'
|
|
163
174
|
assert_no_select 'form label input'
|
|
164
175
|
end
|
|
165
176
|
|
|
177
|
+
test 'collection radio accepts a block to render the radio and label as required' do
|
|
178
|
+
with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s do |label_for, text, value, html_options|
|
|
179
|
+
label(:user, label_for, text) { radio_button(:user, :active, value, html_options) }
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
assert_select 'form label[for=user_active_true] > input#user_active_true[type=radio]'
|
|
183
|
+
assert_select 'form label[for=user_active_false] > input#user_active_false[type=radio]'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
test 'collection_radio helper is deprecated in favor of collection_radio_buttons' do
|
|
187
|
+
assert_deprecated "[SIMPLE_FORM] The `collection_radio` helper is deprecated, " \
|
|
188
|
+
"please use `collection_radio_buttons` instead" do
|
|
189
|
+
with_concat_form_for(@user) do |f|
|
|
190
|
+
f.collection_radio :active, [true, false], :to_s, :to_s
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
assert_select 'input[type=radio][value=true]'
|
|
195
|
+
assert_select 'input[type=radio][value=false]'
|
|
196
|
+
end
|
|
197
|
+
|
|
166
198
|
# COLLECTION CHECK BOX
|
|
167
199
|
test 'collection check box accepts a collection and generate a serie of checkboxes for value method' do
|
|
168
200
|
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
169
201
|
with_collection_check_boxes @user, :tag_ids, collection, :id, :name
|
|
170
202
|
|
|
171
|
-
assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]"
|
|
172
203
|
assert_select 'form input#user_tag_ids_1[type=checkbox][value=1]'
|
|
173
204
|
assert_select 'form input#user_tag_ids_2[type=checkbox][value=2]'
|
|
174
205
|
end
|
|
175
206
|
|
|
207
|
+
test 'collection check box generates only one hidden field for the entire collection, to ensure something will be sent back to the server when posting an empty collection' do
|
|
208
|
+
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
209
|
+
with_collection_check_boxes @user, :tag_ids, collection, :id, :name
|
|
210
|
+
|
|
211
|
+
assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]", :count => 1
|
|
212
|
+
end
|
|
213
|
+
|
|
176
214
|
test 'collection check box accepts a collection and generate a serie of checkboxes with labels for label method' do
|
|
177
215
|
collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
|
|
178
216
|
with_collection_check_boxes @user, :tag_ids, collection, :id, :name
|
|
@@ -212,6 +250,16 @@ class BuilderTest < ActionView::TestCase
|
|
|
212
250
|
assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
|
|
213
251
|
end
|
|
214
252
|
|
|
253
|
+
test 'collection check box accepts selected values as :checked option and override the model values' do
|
|
254
|
+
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
255
|
+
@user.tag_ids = [2]
|
|
256
|
+
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => [1, 3]
|
|
257
|
+
|
|
258
|
+
assert_select 'form input[type=checkbox][value=1][checked=checked]'
|
|
259
|
+
assert_select 'form input[type=checkbox][value=3][checked=checked]'
|
|
260
|
+
assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
|
|
261
|
+
end
|
|
262
|
+
|
|
215
263
|
test 'collection check box accepts multiple disabled items' do
|
|
216
264
|
collection = (1..3).map{|i| [i, "Tag #{i}"] }
|
|
217
265
|
with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => [1, 3]
|
|
@@ -262,71 +310,108 @@ class BuilderTest < ActionView::TestCase
|
|
|
262
310
|
assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'
|
|
263
311
|
end
|
|
264
312
|
|
|
265
|
-
test 'collection check
|
|
266
|
-
|
|
267
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
313
|
+
test 'collection check boxes wraps the collection in the given collection wrapper tag' do
|
|
314
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
268
315
|
|
|
269
|
-
|
|
270
|
-
assert_select 'form ul input[type=checkbox][value=false]#user_active_false'
|
|
271
|
-
end
|
|
316
|
+
assert_select 'form ul input[type=checkbox]', :count => 2
|
|
272
317
|
end
|
|
273
318
|
|
|
274
|
-
test 'collection check
|
|
275
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
319
|
+
test 'collection check boxes does not render any wrapper tag by default' do
|
|
320
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
276
321
|
|
|
277
|
-
assert_select 'form
|
|
278
|
-
|
|
322
|
+
assert_select 'form input[type=checkbox]', :count => 2
|
|
323
|
+
assert_no_select 'form ul'
|
|
279
324
|
end
|
|
280
325
|
|
|
281
|
-
test 'collection check
|
|
282
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
|
|
326
|
+
test 'collection check boxes does not wrap the collection when given falsy values' do
|
|
327
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
|
|
283
328
|
|
|
284
|
-
assert_select 'form
|
|
285
|
-
|
|
329
|
+
assert_select 'form input[type=checkbox]', :count => 2
|
|
330
|
+
assert_no_select 'form ul'
|
|
286
331
|
end
|
|
287
332
|
|
|
288
|
-
test 'collection check
|
|
289
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
333
|
+
test 'collection check boxes uses the given class for collection wrapper tag' do
|
|
334
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
|
|
335
|
+
:collection_wrapper_tag => :ul, :collection_wrapper_class => "items-list"
|
|
336
|
+
|
|
337
|
+
assert_select 'form ul.items-list input[type=checkbox]', :count => 2
|
|
338
|
+
end
|
|
290
339
|
|
|
340
|
+
test 'collection check boxes uses no class for collection wrapper tag when no wrapper tag is given' do
|
|
341
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
|
|
342
|
+
:collection_wrapper_class => "items-list"
|
|
343
|
+
|
|
344
|
+
assert_select 'form input[type=checkbox]', :count => 2
|
|
291
345
|
assert_no_select 'form ul'
|
|
346
|
+
assert_no_select '.items-list'
|
|
292
347
|
end
|
|
293
348
|
|
|
294
|
-
test 'collection check
|
|
295
|
-
|
|
296
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
349
|
+
test 'collection check boxes uses no class for collection wrapper tag by default' do
|
|
350
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
|
|
297
351
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
352
|
+
assert_select 'form ul'
|
|
353
|
+
assert_no_select 'form ul[class]'
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
test 'collection check boxes wrap items in a span tag by default' do
|
|
357
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
358
|
+
|
|
359
|
+
assert_select 'form span input[type=checkbox]', :count => 2
|
|
301
360
|
end
|
|
302
361
|
|
|
303
|
-
test 'collection check
|
|
362
|
+
test 'collection check boxes wraps each item in the given item wrapper tag' do
|
|
304
363
|
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
|
|
305
364
|
|
|
306
|
-
assert_select 'form li input[type=checkbox]
|
|
307
|
-
assert_select 'form li input[type=checkbox][value=false]#user_active_false'
|
|
365
|
+
assert_select 'form li input[type=checkbox]', :count => 2
|
|
308
366
|
end
|
|
309
367
|
|
|
310
|
-
test 'collection check
|
|
368
|
+
test 'collection check boxes does not wrap each item when given explicitly falsy value' do
|
|
311
369
|
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => false
|
|
312
370
|
|
|
313
|
-
assert_select 'form
|
|
314
|
-
|
|
371
|
+
assert_select 'form input[type=checkbox]'
|
|
372
|
+
assert_no_select 'form span input[type=checkbox]'
|
|
315
373
|
end
|
|
316
374
|
|
|
317
|
-
test 'collection check
|
|
318
|
-
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
375
|
+
test 'collection check boxes uses the given class for item wrapper tag' do
|
|
376
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
|
|
377
|
+
:item_wrapper_tag => :li, :item_wrapper_class => "inline"
|
|
378
|
+
|
|
379
|
+
assert_select "form li.inline input[type=checkbox]", :count => 2
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
test 'collection check boxes uses no class for item wrapper tag when no wrapper tag is given' do
|
|
383
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
|
|
384
|
+
:item_wrapper_tag => nil, :item_wrapper_class => "inline"
|
|
385
|
+
|
|
386
|
+
assert_select 'form input[type=checkbox]', :count => 2
|
|
387
|
+
assert_no_select 'form li'
|
|
388
|
+
assert_no_select '.inline'
|
|
389
|
+
end
|
|
319
390
|
|
|
320
|
-
|
|
321
|
-
|
|
391
|
+
test 'collection check boxes uses no class for item wrapper tag by default' do
|
|
392
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
|
|
393
|
+
:item_wrapper_tag => :li
|
|
394
|
+
|
|
395
|
+
assert_select "form li", :count => 2
|
|
396
|
+
assert_no_select "form li[class]"
|
|
322
397
|
end
|
|
323
398
|
|
|
324
399
|
test 'collection check box does not wrap input inside the label' do
|
|
325
400
|
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
|
|
326
401
|
|
|
402
|
+
assert_select 'form input[type=checkbox] + label'
|
|
327
403
|
assert_no_select 'form label input'
|
|
328
404
|
end
|
|
329
405
|
|
|
406
|
+
test 'collection check box accepts a block to render the radio and label as required' do
|
|
407
|
+
with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s do |label_for, text, value, html_options|
|
|
408
|
+
label(:user, label_for, text) { check_box(:user, :active, html_options, value) }
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
assert_select 'form label[for=user_active_true] > input#user_active_true[type=checkbox]'
|
|
412
|
+
assert_select 'form label[for=user_active_false] > input#user_active_false[type=checkbox]'
|
|
413
|
+
end
|
|
414
|
+
|
|
330
415
|
# SIMPLE FIELDS
|
|
331
416
|
test 'simple fields for is available and yields an instance of FormBuilder' do
|
|
332
417
|
with_concat_form_for(@user) do |f|
|
|
@@ -364,4 +449,14 @@ class BuilderTest < ActionView::TestCase
|
|
|
364
449
|
end
|
|
365
450
|
end
|
|
366
451
|
end
|
|
452
|
+
|
|
453
|
+
test 'fields inherites wrapper option from the parent form' do
|
|
454
|
+
swap_wrapper :another do
|
|
455
|
+
simple_form_for(:user, :wrapper => :another) do |f|
|
|
456
|
+
f.simple_fields_for(:company) do |company|
|
|
457
|
+
assert_equal :another, company.options[:wrapper]
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
end
|
|
367
462
|
end
|