diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e51ef160..963654c14 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,13 @@
-## [Pending Release][]
+## [Pending Release][] (2016-10-18)
Bugfixes:
- - Your contribution here!
+ - Change error class from `has-error` to `has-danger`
+ - Change validation text class from `help-block` to `form-control-feedback`
+ - Change help text class from `help-block` to `form-text text-muted`
+ - Change checkbox classes from `checkbox` to `form-check` and added `form-check-label` to labels
Features:
- - Your contribution here!
+ - Update to Bootstrap v4
## [2.5.2][] (2016-10-08)
diff --git a/README.md b/README.md
index 1bf9ab036..34d8a0c8e 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ twitter bootstrap-style forms into your rails application.
* Ruby 1.9+
* Rails 4.0+
-* Twitter Bootstrap 3.0+
+* Twitter Bootstrap 4.0+
## Installation
@@ -468,10 +468,10 @@ error will be displayed below the field. Rails normally wraps the fields in a
div (field_with_errors), but this behavior is suppressed. Here's an example:
```html
-
+
- can't be blank
+
can't be blank
```
diff --git a/lib/bootstrap_form/form_builder.rb b/lib/bootstrap_form/form_builder.rb
index d89c96643..77d50e7c7 100644
--- a/lib/bootstrap_form/form_builder.rb
+++ b/lib/bootstrap_form/form_builder.rb
@@ -111,6 +111,7 @@ def time_zone_select_with_bootstrap(method, priority_zones = nil, options = {},
def check_box_with_bootstrap(name, options = {}, checked_value = "1", unchecked_value = "0", &block)
options = options.symbolize_keys!
check_box_options = options.except(:label, :label_class, :help, :inline)
+ check_box_options[:class] = ["form-check-input", check_box_options[:class]].compact.join(' ')
html = check_box_without_bootstrap(name, check_box_options, checked_value, unchecked_value)
label_content = block_given? ? capture(&block) : options[:label]
@@ -126,13 +127,13 @@ def check_box_with_bootstrap(name, options = {}, checked_value = "1", unchecked_
end
disabled_class = " disabled" if options[:disabled]
- label_class = options[:label_class]
if options[:inline]
- label_class = " #{label_class}" if label_class
- label(label_name, html, class: "checkbox-inline#{disabled_class}#{label_class}")
+ label_class = " #{options[:label_class]}" if options[:label_class]
+ label(label_name, html, class: "form-check-inline#{disabled_class}#{label_class}")
else
- content_tag(:div, class: "checkbox#{disabled_class}") do
+ label_class = ["form-check-label", options[:label_class]].compact.join(' ')
+ content_tag(:div, class: "form-check#{disabled_class}") do
label(label_name, html, class: label_class)
end
end
@@ -201,6 +202,7 @@ def form_group(*args, &block)
label = generate_label(options[:id], name, options[:label], options[:label_col], options[:layout]) if options[:label]
control = capture(&block).to_s
control.concat(generate_help(name, options[:help]).to_s)
+ # TODO create `generate_error`
control.concat(generate_icon(options[:icon])) if options[:icon]
if get_group_layout(options[:layout]) == :horizontal
@@ -263,7 +265,7 @@ def label_class
end
def error_class
- "has-error"
+ "has-danger"
end
def feedback_class
@@ -385,12 +387,19 @@ def generate_label(id, name, options, custom_label_col, group_layout)
end
def generate_help(name, help_text)
- help_text = get_error_messages(name) if has_error?(name) && inline_errors
+ if is_error = has_error?(name) && inline_errors
+ help_text = get_error_messages(name)
+ end
return if help_text === false
help_text ||= get_help_text_by_i18n_key(name)
- content_tag(:span, help_text, class: 'help-block') if help_text.present?
+ return if help_text.blank?
+ if is_error
+ content_tag(:div, help_text, class: 'form-control-feedback')
+ else
+ content_tag(:p, help_text, class: 'form-text text-muted')
+ end
end
def generate_icon(icon)
diff --git a/test/bootstrap_checkbox_test.rb b/test/bootstrap_checkbox_test.rb
index e9ae6eab9..64093947f 100644
--- a/test/bootstrap_checkbox_test.rb
+++ b/test/bootstrap_checkbox_test.rb
@@ -8,74 +8,74 @@ def setup
end
test "check_box is wrapped correctly" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label: 'I agree to the terms')
end
test "disabled check_box has proper wrapper classes" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label: 'I agree to the terms', disabled: true)
end
test "check_box label allows html" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label: %{I agree to the terms}.html_safe)
end
test "check_box accepts a block to define the label" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms) { "I agree to the terms" }
end
test "check_box accepts a custom label class" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label_class: 'btn')
end
test "check_box responds to checked_value and unchecked_value arguments" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, {label: 'I agree to the terms'}, 'yes', 'no')
end
test "inline checkboxes" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true)
end
test "disabled inline check_box" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, label: 'I agree to the terms', inline: true, disabled: true)
end
test "inline checkboxes with custom label class" do
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.check_box(:terms, inline: true, label_class: 'btn')
end
test 'collection_check_boxes renders the form_group correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
- expected = %{
With a help!
}
+ expected = %{
With a help!
}
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, :street, label: 'This is a checkbox collection', help: 'With a help!')
end
test 'collection_check_boxes renders multiple checkboxes correctly' do
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
- expected = %{
}
+ expected = %{
}
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, :street)
end
test 'collection_check_boxes renders inline checkboxes correctly' do
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
- expected = %{}
+ expected = %{}
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, :street, inline: true)
end
test 'collection_check_boxes renders with checked option correctly' do
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
- expected = %{
A good password should be at least six characters long
}
+ expected = %{
A good password should be at least six characters long
}
assert_equal expected, @builder.password_field(:password)
end
diff --git a/test/bootstrap_form_group_test.rb b/test/bootstrap_form_group_test.rb
index 72b0e93c9..c0a35c1dd 100644
--- a/test/bootstrap_form_group_test.rb
+++ b/test/bootstrap_form_group_test.rb
@@ -77,17 +77,17 @@ def setup
end
test "help messages for default forms" do
- expected = %{
This is required
}
+ expected = %{
This is required
}
assert_equal expected, @builder.text_field(:email, help: 'This is required')
end
test "help messages for horizontal forms" do
- expected = %{
This is required
}
+ expected = %{
This is required
}
assert_equal expected, @horizontal_builder.text_field(:email, help: "This is required")
end
test "help messages to look up I18n automatically" do
- expected = %{
A good password should be at least six characters long
}
+ expected = %{
A good password should be at least six characters long
}
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, :street, label: 'This is a radio button collection', help: 'With a help!')
end
@@ -67,14 +67,14 @@ def setup
test 'collection_radio_buttons renders label defined by Proc correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
- expected = %{
With a help!
}
+ expected = %{
With a help!
}
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, Proc.new { |a| a.street.reverse }, label: 'This is a radio button collection', help: 'With a help!')
end
test 'collection_radio_buttons renders value defined by Proc correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
- expected = %{
With a help!
}
+ expected = %{
With a help!
}
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, label: 'This is a radio button collection', help: 'With a help!')
end
@@ -95,14 +95,14 @@ def setup
test 'collection_radio_buttons renders label defined by lambda correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
- expected = %{
With a help!
}
+ expected = %{
With a help!
}
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, lambda { |a| a.street.reverse }, label: 'This is a radio button collection', help: 'With a help!')
end
test 'collection_radio_buttons renders value defined by lambda correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
- expected = %{
With a help!
}
+ expected = %{
With a help!
}
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, label: 'This is a radio button collection', help: 'With a help!')
end
diff --git a/test/bootstrap_selects_test.rb b/test/bootstrap_selects_test.rb
index 8812d6f2a..84b207560 100644
--- a/test/bootstrap_selects_test.rb
+++ b/test/bootstrap_selects_test.rb
@@ -18,7 +18,7 @@ def setup
end
test "bootstrap_specific options are handled correctly" do
- expected = %{
Help!
}
+ expected = %{
Help!
}
assert_equal expected, @builder.select(:status, [['activated', 1], ['blocked', 2]], label: "My Status Label", help: "Help!" )
end