Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Features:
- Use humanized attribute name in label errors (#146, @atipugin)
- Allow to skip label rendering (#145, @atipugin)
- Added a `required` CSS class for labels with required attributes (#150, @krsyoung)
- Added option to customize labels' class.

## 2.2.0 (2014-09-16)

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ class, which keeps your labels accessible to those using screen readers.
```erb
<%= f.text_area :comment, hide_label: :true, placeholder: "Leave a comment..." %>
```

To add custom classes to the field's label:

```erb
<%= f.text_field :email, label_class: "custom-class" %>
```

#### Required Fields

A label that is associated with a required field is automatically annotated with
Expand Down
29 changes: 18 additions & 11 deletions lib/bootstrap_form/form_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,24 @@ 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)

html = check_box_without_bootstrap(name, options.except(:label, :help, :inline), checked_value, unchecked_value)
html = check_box_without_bootstrap(name, check_box_options, checked_value, unchecked_value)
label_content = block_given? ? capture(&block) : options[:label]
html.concat(" ").concat(label_content || (object && object.class.human_attribute_name(name)) || name.to_s.humanize)

label_name = name
label_name = "#{name}_#{checked_value}" if options[:multiple]

disabled_class = options[:disabled] ? " disabled" : ""
disabled_class = " disabled" if options[:disabled]
label_class = options[:label_class]

if options[:inline]
label(label_name, html, class: "checkbox-inline#{disabled_class}")
label_class = " #{label_class}" if label_class
label(label_name, html, class: "checkbox-inline#{disabled_class}#{label_class}")
else
content_tag(:div, class: "checkbox#{disabled_class}") do
label(label_name, html)
label(label_name, html, class: label_class)
end
end
end
Expand All @@ -123,16 +126,19 @@ def check_box_with_bootstrap(name, options = {}, checked_value = "1", unchecked_

def radio_button_with_bootstrap(name, value, *args)
options = args.extract_options!.symbolize_keys!
args << options.except(:label, :help, :inline)
args << options.except(:label, :label_class, :help, :inline)

html = radio_button_without_bootstrap(name, value, *args) + " " + options[:label]
disabled_class = options[:disabled] ? " disabled" : ""

disabled_class = " disabled" if options[:disabled]
label_class = options[:label_class]

if options[:inline]
label(name, html, class: "radio-inline#{disabled_class}", value: value)
label_class = " #{label_class}" if label_class
label(name, html, class: "radio-inline#{disabled_class}#{label_class}", value: value)
else
content_tag(:div, class: "radio#{disabled_class}") do
label(name, html, value: value)
label(name, html, value: value, class: label_class)
end
end
end
Expand Down Expand Up @@ -276,8 +282,6 @@ def form_group_builder(method, options, html_options = nil)

options = convert_form_tag_options(method, options) if acts_like_form_tag

label = options.delete(:label)
label_class = hide_class if options.delete(:hide_label)
wrapper_class = options.delete(:wrapper_class)
wrapper_options = options.delete(:wrapper)
help = options.delete(:help)
Expand All @@ -300,8 +304,11 @@ def form_group_builder(method, options, html_options = nil)
end

unless options.delete(:skip_label)
label_class = hide_class if options.delete(:hide_label)
label_class ||= options.delete(:label_class)

form_group_options.reverse_merge!(label: {
text: label,
text: options.delete(:label),
class: label_class
})
end
Expand Down
10 changes: 10 additions & 0 deletions test/bootstrap_checkbox_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ def setup
assert_equal expected, @builder.check_box(:terms) { "I agree to the terms" }
end

test "check_box accepts a custom label class" do
expected = %{<div class="checkbox"><label class="btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label></div>}
assert_equal expected, @builder.check_box(:terms, label_class: 'btn')
end

test "check_box responds to checked_value and unchecked_value arguments" do
expected = %{<div class="checkbox"><label for="user_terms"><input name="user[terms]" type="hidden" value="no" /><input id="user_terms" name="user[terms]" type="checkbox" value="yes" /> I agree to the terms</label></div>}
assert_equal expected, @builder.check_box(:terms, {label: 'I agree to the terms'}, 'yes', 'no')
Expand All @@ -42,6 +47,11 @@ def setup
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 = %{<label class="checkbox-inline btn" for="user_terms"><input name="user[terms]" type="hidden" value="0" /><input id="user_terms" name="user[terms]" type="checkbox" value="1" /> Terms</label>}
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 = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="control-label" for="user_misc">This is a checkbox collection</label><div class="checkbox"><label for="user_misc_1"><input id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> Foobar</label></div><span class="help-block">With a help!</span></div>}
Expand Down
5 changes: 5 additions & 0 deletions test/bootstrap_form_group_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ def setup
assert_equal expected, @builder.text_field(:email, hide_label: true)
end

test "adding a custom label class" do
expected = %{<div class="form-group"><label class="btn 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>}
assert_equal expected, @builder.text_field(:email, label_class: 'btn')
end

test "skipping a label" do
expected = %{<div class="form-group"><input class="form-control" id="user_email" name="user[email]" type="text" value="steve@example.com" /></div>}
assert_equal expected, @builder.text_field(:email, skip_label: true)
Expand Down
20 changes: 15 additions & 5 deletions test/bootstrap_radio_button_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,31 @@ def setup
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button')
end

test "radio_button inline label is set correctly" do
expected = %{<label class="radio-inline" for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', inline: true)
end

test "radio_button disabled label is set correctly" do
expected = %{<div class="radio disabled"><label for="user_misc_1"><input disabled="disabled" id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label></div>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', disabled: true)
end

test "radio_button label class is set correctly" do
expected = %{<div class="radio"><label class="btn" for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label></div>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', label_class: 'btn')
end

test "radio_button inline label is set correctly" do
expected = %{<label class="radio-inline" for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', inline: true)
end

test "radio_button disabled inline label is set correctly" do
expected = %{<label class="radio-inline disabled" for="user_misc_1"><input disabled="disabled" id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', inline: true, disabled: true)
end

test "radio_button inline label class is set correctly" do
expected = %{<label class="radio-inline btn" for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> This is a radio button</label>}
assert_equal expected, @builder.radio_button(:misc, '1', label: 'This is a radio button', inline: true, label_class: 'btn')
end

test 'collection_radio_buttons renders the form_group correctly' do
collection = [Address.new(id: 1, street: 'Foobar')]
expected = %{<div class="form-group"><label class="control-label" for="user_misc">This is a radio button collection</label><div class="radio"><label for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> Foobar</label></div><span class="help-block">With a help!</span></div>}
Expand Down