comfy_bootstrap_form 4.0.0.beta1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +621 -0
- data/Rakefile +37 -0
- data/app/assets/stylesheets/rails_bootstrap_forms.css +10 -0
- data/lib/bootstrap_form.rb +13 -0
- data/lib/bootstrap_form/aliasing.rb +35 -0
- data/lib/bootstrap_form/form_builder.rb +460 -0
- data/lib/bootstrap_form/helper.rb +36 -0
- data/lib/bootstrap_form/helpers/bootstrap.rb +94 -0
- data/lib/bootstrap_form/helpers/nested_form.rb +33 -0
- data/lib/bootstrap_form/version.rb +3 -0
- data/lib/comfy_bootstrap_form.rb +1 -0
- data/test/bootstrap_checkbox_test.rb +144 -0
- data/test/bootstrap_fields_test.rb +152 -0
- data/test/bootstrap_form_group_test.rb +313 -0
- data/test/bootstrap_form_test.rb +276 -0
- data/test/bootstrap_other_components_test.rb +86 -0
- data/test/bootstrap_radio_button_test.rb +124 -0
- data/test/bootstrap_selects_test.rb +160 -0
- data/test/dummy/Gemfile +45 -0
- data/test/dummy/Gemfile.lock +120 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +10 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/address.rb +3 -0
- data/test/dummy/app/models/faux_user.rb +9 -0
- data/test/dummy/app/models/super_user.rb +2 -0
- data/test/dummy/app/models/user.rb +9 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +4 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +53 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/generic_migration.rb +6 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/db/migrate/20130703191909_create_users.rb +13 -0
- data/test/dummy/db/migrate/20130703191937_create_addresses.rb +13 -0
- data/test/dummy/db/migrate/20130912171202_add_preferences_to_user.rb +5 -0
- data/test/dummy/db/migrate/20140327190145_add_terms_to_user.rb +5 -0
- data/test/dummy/db/migrate/20140922133133_add_type_to_users.rb +5 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +18394 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/test/fixtures/addresses.yml +15 -0
- data/test/dummy/test/fixtures/users.yml +15 -0
- data/test/dummy/test/models/address_test.rb +7 -0
- data/test/dummy/test/models/user_test.rb +7 -0
- data/test/dummy/test/test_helper.rb +15 -0
- data/test/special_form_class_models_test.rb +43 -0
- data/test/test_helper.rb +86 -0
- metadata +309 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'helpers/nested_form'
|
2
|
+
|
3
|
+
module BootstrapForm
|
4
|
+
module Helper
|
5
|
+
include ::BootstrapForm::Helpers::NestedForm
|
6
|
+
|
7
|
+
def bootstrap_form_for(object, options = {}, &block)
|
8
|
+
options.reverse_merge!({builder: BootstrapForm::FormBuilder})
|
9
|
+
|
10
|
+
options[:html] ||= {}
|
11
|
+
options[:html][:role] ||= 'form'
|
12
|
+
|
13
|
+
if options[:layout] == :inline
|
14
|
+
options[:html][:class] = [options[:html][:class], "form-inline"].compact.join(" ")
|
15
|
+
end
|
16
|
+
|
17
|
+
temporarily_disable_field_error_proc do
|
18
|
+
form_for(object, options, &block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def bootstrap_form_tag(options = {}, &block)
|
23
|
+
options[:acts_like_form_tag] = true
|
24
|
+
|
25
|
+
bootstrap_form_for("", options, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def temporarily_disable_field_error_proc
|
29
|
+
original_proc = ActionView::Base.field_error_proc
|
30
|
+
ActionView::Base.field_error_proc = proc { |input, instance| input }
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
ActionView::Base.field_error_proc = original_proc
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module BootstrapForm
|
2
|
+
module Helpers
|
3
|
+
module Bootstrap
|
4
|
+
def submit(name = nil, options = {})
|
5
|
+
options.reverse_merge! class: 'btn btn-secondary'
|
6
|
+
super(name, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def primary(name = nil, options = {})
|
10
|
+
options.reverse_merge! class: 'btn btn-primary'
|
11
|
+
submit(name, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def alert_message(title, options = {})
|
15
|
+
css = options[:class] || 'alert alert-danger'
|
16
|
+
|
17
|
+
if object.respond_to?(:errors) && object.errors.full_messages.any?
|
18
|
+
content_tag :div, class: css do
|
19
|
+
concat content_tag :p, title
|
20
|
+
concat error_summary unless options[:error_summary] == false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def error_summary
|
26
|
+
content_tag :ul, class: 'rails-bootstrap-forms-error-summary' do
|
27
|
+
object.errors.full_messages.each do |error|
|
28
|
+
concat content_tag(:li, error)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def errors_on(name, options = {})
|
34
|
+
if has_error?(name)
|
35
|
+
hide_attribute_name = options[:hide_attribute_name] || false
|
36
|
+
|
37
|
+
content_tag :div, class: "alert alert-danger" do
|
38
|
+
if hide_attribute_name
|
39
|
+
object.errors[name].join(", ")
|
40
|
+
else
|
41
|
+
object.errors.full_messages_for(name).join(", ")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def static_control(*args, &block)
|
48
|
+
options = args.extract_options!
|
49
|
+
name = args.first
|
50
|
+
|
51
|
+
html = if block_given?
|
52
|
+
capture(&block)
|
53
|
+
else
|
54
|
+
object.send(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
form_group_builder(name, options) do
|
58
|
+
content_tag(:p, html, class: static_class)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def custom_control(*args, &block)
|
63
|
+
options = args.extract_options!
|
64
|
+
name = args.first
|
65
|
+
|
66
|
+
form_group_builder(name, options, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def prepend_and_append_input(options, &block)
|
70
|
+
options = options.extract!(:prepend, :append, :input_group_class)
|
71
|
+
input_group_class = ["input-group", options[:input_group_class]].compact.join(' ')
|
72
|
+
|
73
|
+
input = capture(&block)
|
74
|
+
|
75
|
+
input = content_tag(:span, options[:prepend], class: input_group_class(options[:prepend])) + input if options[:prepend]
|
76
|
+
input << content_tag(:span, options[:append], class: input_group_class(options[:append])) if options[:append]
|
77
|
+
input = content_tag(:div, input, class: input_group_class) unless options.empty?
|
78
|
+
input
|
79
|
+
end
|
80
|
+
|
81
|
+
def input_group_class(add_on_content)
|
82
|
+
if add_on_content.match(/btn/)
|
83
|
+
'input-group-btn'
|
84
|
+
else
|
85
|
+
'input-group-addon'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def static_class
|
90
|
+
"form-control-static"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
begin
|
2
|
+
require 'nested_form/builder_mixin'
|
3
|
+
|
4
|
+
module BootstrapForm
|
5
|
+
class NestedFormBuilder < ::BootstrapForm::FormBuilder
|
6
|
+
include ::NestedForm::BuilderMixin
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module BootstrapForm
|
11
|
+
module Helpers
|
12
|
+
module NestedForm
|
13
|
+
def bootstrap_nested_form_for(object, options = {}, &block)
|
14
|
+
options.reverse_merge!({builder: BootstrapForm::NestedFormBuilder})
|
15
|
+
bootstrap_form_for(object, options) do |f|
|
16
|
+
capture(f, &block).to_s << after_nested_form_callbacks
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
rescue LoadError
|
24
|
+
module BootstrapForm
|
25
|
+
module Helpers
|
26
|
+
module NestedForm
|
27
|
+
def bootstrap_nested_form_for(object, options = {}, &block)
|
28
|
+
raise 'nested_forms was not found. Is it in your Gemfile?'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "./bootstrap_form"
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BootstrapCheckboxTest < ActionView::TestCase
|
4
|
+
include BootstrapForm::Helper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
setup_test_fixture
|
8
|
+
end
|
9
|
+
|
10
|
+
test "check_box is wrapped correctly" do
|
11
|
+
expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
|
12
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms')
|
13
|
+
end
|
14
|
+
|
15
|
+
test "disabled check_box has proper wrapper classes" do
|
16
|
+
expected = %{<div class="form-check disabled"><label class="form-check-label" for="user_terms"><input disabled="disabled" name="user[terms]" type="hidden" value="0" /><input class="form-check-input" disabled="disabled" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
|
17
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', disabled: true)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "check_box label allows html" do
|
21
|
+
expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the <a href="#">terms</a></label></div>}
|
22
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label: %{I agree to the <a href="#">terms</a>}.html_safe)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "check_box accepts a block to define the label" do
|
26
|
+
expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label></div>}
|
27
|
+
assert_equivalent_xml expected, @builder.check_box(:terms) { "I agree to the terms" }
|
28
|
+
end
|
29
|
+
|
30
|
+
test "check_box accepts a custom label class" do
|
31
|
+
expected = %{<div class="form-check"><label class="form-check-label btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label></div>}
|
32
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label_class: 'btn')
|
33
|
+
end
|
34
|
+
|
35
|
+
test "check_box responds to checked_value and unchecked_value arguments" do
|
36
|
+
expected = %{<div class="form-check"><label class="form-check-label" for="user_terms"><input name="user[terms]" type="hidden" value="no" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="yes" /> I agree to the terms</label></div>}
|
37
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, {label: 'I agree to the terms'}, 'yes', 'no')
|
38
|
+
end
|
39
|
+
|
40
|
+
test "inline checkboxes" do
|
41
|
+
expected = %{<label class="form-check-inline" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label>}
|
42
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true)
|
43
|
+
end
|
44
|
+
|
45
|
+
test "disabled inline check_box" do
|
46
|
+
expected = %{<label class="form-check-inline disabled" for="user_terms"><input disabled="disabled" name="user[terms]" type="hidden" value="0" /><input class="form-check-input" disabled="disabled" id="user_terms" name="user[terms]" type="checkbox" value="1" /> I agree to the terms</label>}
|
47
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true, disabled: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
test "inline checkboxes with custom label class" do
|
51
|
+
expected = %{<label class="form-check-inline btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input class="form-check-input" id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label>}
|
52
|
+
assert_equivalent_xml expected, @builder.check_box(:terms, inline: true, label_class: 'btn')
|
53
|
+
end
|
54
|
+
|
55
|
+
test 'collection_check_boxes renders the form_group correctly' do
|
56
|
+
collection = [Address.new(id: 1, street: 'Foobar')]
|
57
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">This is a checkbox collection</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foobar</label></div><span class="form-text text-muted">With a help!</span></div>}
|
58
|
+
|
59
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, label: 'This is a checkbox collection', help: 'With a help!')
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'collection_check_boxes renders multiple checkboxes correctly' do
|
63
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
64
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
|
65
|
+
|
66
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street)
|
67
|
+
end
|
68
|
+
|
69
|
+
test 'collection_check_boxes renders inline checkboxes correctly' do
|
70
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
71
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><label class="form-check-inline" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label><label class="form-check-inline" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div>}
|
72
|
+
|
73
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, inline: true)
|
74
|
+
end
|
75
|
+
|
76
|
+
test 'collection_check_boxes renders with checked option correctly' do
|
77
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
78
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input checked="checked" class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
|
79
|
+
|
80
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: 1)
|
81
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: collection.first)
|
82
|
+
end
|
83
|
+
|
84
|
+
test 'collection_check_boxes renders with multiple checked options correctly' do
|
85
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
86
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input checked="checked" class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input checked="checked" class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> Bar</label></div></div>}
|
87
|
+
|
88
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: [1, 2])
|
89
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: collection)
|
90
|
+
end
|
91
|
+
|
92
|
+
test 'collection_check_boxes sanitizes values when generating label `for`' do
|
93
|
+
collection = [Address.new(id: 1, street: 'Foo St')]
|
94
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_foo_st"><input class="form-check-input" id="user_misc_foo_st" name="user[misc][]" type="checkbox" value="Foo St" /> Foo St</label></div></div>}
|
95
|
+
|
96
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :street, :street)
|
97
|
+
end
|
98
|
+
|
99
|
+
test 'collection_check_boxes renders multiple checkboxes with labels defined by Proc :text_method correctly' do
|
100
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
101
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
|
102
|
+
|
103
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, Proc.new { |a| a.street.reverse })
|
104
|
+
end
|
105
|
+
|
106
|
+
test 'collection_check_boxes renders multiple checkboxes with values defined by Proc :value_method correctly' do
|
107
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
108
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
|
109
|
+
|
110
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street)
|
111
|
+
end
|
112
|
+
|
113
|
+
test 'collection_check_boxes renders multiple checkboxes with labels defined by lambda :text_method correctly' do
|
114
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
115
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_1"><input class="form-check-input" id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="form-check"><label class="form-check-label" for="user_misc_2"><input class="form-check-input" id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
|
116
|
+
|
117
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, :id, lambda { |a| a.street.reverse })
|
118
|
+
end
|
119
|
+
|
120
|
+
test 'collection_check_boxes renders multiple checkboxes with values defined by lambda :value_method correctly' do
|
121
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
122
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
|
123
|
+
|
124
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street)
|
125
|
+
end
|
126
|
+
|
127
|
+
test 'collection_check_boxes renders with checked option correctly with Proc :value_method' do
|
128
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
129
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input checked="checked" class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
|
130
|
+
|
131
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: "address_1")
|
132
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: collection.first)
|
133
|
+
end
|
134
|
+
|
135
|
+
test 'collection_check_boxes renders with multiple checked options correctly with lambda :value_method' do
|
136
|
+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
|
137
|
+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><div class="form-check"><label class="form-check-label" for="user_misc_address_1"><input checked="checked" class="form-check-input" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="form-check"><label class="form-check-label" for="user_misc_address_2"><input checked="checked" class="form-check-input" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
|
138
|
+
|
139
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: ["address_1", "address_2"])
|
140
|
+
assert_equivalent_xml expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: collection)
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BootstrapFieldsTest < ActionView::TestCase
|
4
|
+
include BootstrapForm::Helper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
setup_test_fixture
|
8
|
+
end
|
9
|
+
|
10
|
+
test "color fields are wrapped correctly" do
|
11
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="color" value="#000000" /></div>}
|
12
|
+
assert_equivalent_xml expected, @builder.color_field(:misc)
|
13
|
+
end
|
14
|
+
|
15
|
+
test "date fields are wrapped correctly" do
|
16
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="date" /></div>}
|
17
|
+
assert_equivalent_xml expected, @builder.date_field(:misc)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "date time fields are wrapped correctly" do
|
21
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="datetime" /></div>}
|
22
|
+
assert_equivalent_xml expected, @builder.datetime_field(:misc)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "date time local fields are wrapped correctly" do
|
26
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="datetime-local" /></div>}
|
27
|
+
assert_equivalent_xml expected, @builder.datetime_local_field(:misc)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "email fields are wrapped correctly" do
|
31
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="email" /></div>}
|
32
|
+
assert_equivalent_xml expected, @builder.email_field(:misc)
|
33
|
+
end
|
34
|
+
|
35
|
+
test "file fields are wrapped correctly" do
|
36
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input id="user_misc" name="user[misc]" type="file" /></div>}
|
37
|
+
assert_equivalent_xml expected, @builder.file_field(:misc)
|
38
|
+
end
|
39
|
+
|
40
|
+
test "hidden fields are supported" do
|
41
|
+
expected = %{<input id="user_misc" name="user[misc]" type="hidden" />}
|
42
|
+
assert_equivalent_xml expected, @builder.hidden_field(:misc)
|
43
|
+
end
|
44
|
+
|
45
|
+
test "month local fields are wrapped correctly" do
|
46
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="month" /></div>}
|
47
|
+
assert_equivalent_xml expected, @builder.month_field(:misc)
|
48
|
+
end
|
49
|
+
|
50
|
+
test "number fields are wrapped correctly" do
|
51
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="number" /></div>}
|
52
|
+
assert_equivalent_xml expected, @builder.number_field(:misc)
|
53
|
+
end
|
54
|
+
|
55
|
+
test "password fields are wrapped correctly" do
|
56
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_password">Password</label><input class="form-control" id="user_password" name="user[password]" type="password" /><span class="form-text text-muted">A good password should be at least six characters long</span></div>}
|
57
|
+
assert_equivalent_xml expected, @builder.password_field(:password)
|
58
|
+
end
|
59
|
+
|
60
|
+
test "phone/telephone fields are wrapped correctly" do
|
61
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="tel" /></div>}
|
62
|
+
assert_equivalent_xml expected, @builder.phone_field(:misc)
|
63
|
+
assert_equivalent_xml expected, @builder.telephone_field(:misc)
|
64
|
+
end
|
65
|
+
|
66
|
+
test "range fields are wrapped correctly" do
|
67
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="range" /></div>}
|
68
|
+
assert_equivalent_xml expected, @builder.range_field(:misc)
|
69
|
+
end
|
70
|
+
|
71
|
+
test "search fields are wrapped correctly" do
|
72
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="search" /></div>}
|
73
|
+
assert_equivalent_xml expected, @builder.search_field(:misc)
|
74
|
+
end
|
75
|
+
|
76
|
+
test "text areas are wrapped correctly" do
|
77
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_comments">Comments</label><textarea class="form-control" id="user_comments" name="user[comments]">\nmy comment</textarea></div>}
|
78
|
+
assert_equivalent_xml expected, @builder.text_area(:comments)
|
79
|
+
end
|
80
|
+
|
81
|
+
test "text fields are wrapped correctly" do
|
82
|
+
expected = %{<div class="form-group"><label class="form-control-label required" for="user_email">Email</label><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
|
83
|
+
assert_equivalent_xml expected, @builder.text_field(:email)
|
84
|
+
end
|
85
|
+
|
86
|
+
test "time fields are wrapped correctly" do
|
87
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="time" /></div>}
|
88
|
+
assert_equivalent_xml expected, @builder.time_field(:misc)
|
89
|
+
end
|
90
|
+
|
91
|
+
test "url fields are wrapped correctly" do
|
92
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="url" /></div>}
|
93
|
+
assert_equivalent_xml expected, @builder.url_field(:misc)
|
94
|
+
end
|
95
|
+
|
96
|
+
test "week fields are wrapped correctly" do
|
97
|
+
expected = %{<div class="form-group"><label class="form-control-label" for="user_misc">Misc</label><input class="form-control" id="user_misc" name="user[misc]" type="week" /></div>}
|
98
|
+
assert_equivalent_xml expected, @builder.week_field(:misc)
|
99
|
+
end
|
100
|
+
|
101
|
+
test "bootstrap_form_for helper works for associations" do
|
102
|
+
@user.address = Address.new(street: '123 Main Street')
|
103
|
+
|
104
|
+
output = bootstrap_form_for(@user) do |f|
|
105
|
+
f.fields_for :address do |af|
|
106
|
+
af.text_field(:street)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div><div class="form-group"><label class="form-control-label" for="user_address_attributes_street">Street</label><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></form>}
|
111
|
+
assert_equivalent_xml expected, output
|
112
|
+
end
|
113
|
+
|
114
|
+
test "bootstrap_form_for helper works for serialized hash attributes" do
|
115
|
+
@user.preferences = { favorite_color: "cerulean" }
|
116
|
+
|
117
|
+
output = bootstrap_form_for(@user) do |f|
|
118
|
+
f.fields_for :preferences do |builder|
|
119
|
+
builder.text_field :favorite_color, value: @user.preferences[:favorite_color]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div><div class="form-group"><label class="form-control-label" for="user_preferences_favorite_color">Favorite color</label><input class="form-control" id="user_preferences_favorite_color" name="user[preferences][favorite_color]" type="text" value="cerulean" /></div></form>}
|
124
|
+
assert_equivalent_xml expected, output
|
125
|
+
end
|
126
|
+
|
127
|
+
test "fields_for correctly passes horizontal style from parent builder" do
|
128
|
+
@user.address = Address.new(street: '123 Main Street')
|
129
|
+
|
130
|
+
output = bootstrap_form_for(@user, layout: :horizontal, label_col: 'col-sm-2', control_col: 'col-sm-10') do |f|
|
131
|
+
f.fields_for :address do |af|
|
132
|
+
af.text_field(:street)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
expected = %{<form accept-charset="UTF-8" action="/users" class="new_user" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div><div class="form-group row"><label class="form-control-label col-sm-2" for="user_address_attributes_street">Street</label><div class="col-sm-10"><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></div></form>}
|
137
|
+
assert_equivalent_xml expected, output
|
138
|
+
end
|
139
|
+
|
140
|
+
test "fields_for correctly passes inline style from parent builder" do
|
141
|
+
@user.address = Address.new(street: '123 Main Street')
|
142
|
+
|
143
|
+
output = bootstrap_form_for(@user, layout: :inline) do |f|
|
144
|
+
f.fields_for :address do |af|
|
145
|
+
af.text_field(:street)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
expected = %{<form accept-charset="UTF-8" action="/users" class="form-inline" id="new_user" method="post" role="form"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div><div class="form-group"><label class="form-control-label" for="user_address_attributes_street">Street</label><input class="form-control" id="user_address_attributes_street" name="user[address_attributes][street]" type="text" value="123 Main Street" /></div></form>}
|
150
|
+
assert_equivalent_xml expected, output
|
151
|
+
end
|
152
|
+
end
|