Skip to content

Commit b7843ec

Browse files
committed
Allow :value_method and :text_method for collection_check_boxes and collection_radio_buttons to be any Object that responds to , e.g. a Proc or lambda, to match the same functionality as provided by the corresponding Rails form helper methods.
Ensure that a single String checked value does not perform an include? check by converting checked value(s) to an Array.
1 parent 4923808 commit b7843ec

File tree

3 files changed

+110
-6
lines changed

3 files changed

+110
-6
lines changed

lib/bootstrap_form/form_builder.rb

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -363,17 +363,18 @@ def inputs_collection(name, collection, value, text, options = {}, &block)
363363
inputs = ""
364364

365365
collection.each do |obj|
366-
input_options = options.merge(label: obj.send(text))
366+
input_options = options.merge(label: text.respond_to?(:call) ? text.call(obj) : obj.send(text))
367367

368+
input_value = value.respond_to?(:call) ? value.call(obj) : obj.send(value)
368369
if checked = input_options[:checked]
369-
input_options[:checked] = checked == obj.send(value) ||
370-
checked.try(:include?, obj.send(value)) ||
371-
checked == obj ||
372-
checked.try(:include?, obj)
370+
input_options[:checked] = checked == input_value ||
371+
Array(checked).try(:include?, input_value) ||
372+
checked == obj ||
373+
Array(checked).try(:include?, obj)
373374
end
374375

375376
input_options.delete(:class)
376-
inputs << block.call(name, obj.send(value), input_options)
377+
inputs << block.call(name, input_value, input_options)
377378
end
378379

379380
inputs.html_safe

test/bootstrap_checkbox_test.rb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,50 @@ def setup
8888
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: [1, 2])
8989
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, :street, checked: collection)
9090
end
91+
92+
test 'collection_check_boxes renders multiple checkboxes with labels defined by Proc :text_method correctly' do
93+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
94+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_1"><input id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="checkbox"><label for="user_misc_2"><input id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
95+
96+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, Proc.new { |a| a.street.reverse })
97+
end
98+
99+
test 'collection_check_boxes renders multiple checkboxes with values defined by Proc :value_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="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_address_1"><input id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="checkbox"><label for="user_misc_address_2"><input id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
102+
103+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street)
104+
end
105+
106+
test 'collection_check_boxes renders multiple checkboxes with labels defined by lambda :text_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="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_1"><input id="user_misc_1" name="user[misc][]" type="checkbox" value="1" /> ooF</label></div><div class="checkbox"><label for="user_misc_2"><input id="user_misc_2" name="user[misc][]" type="checkbox" value="2" /> raB</label></div></div>}
109+
110+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, :id, lambda { |a| a.street.reverse })
111+
end
112+
113+
test 'collection_check_boxes renders multiple checkboxes with values defined by lambda :value_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="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_address_1"><input id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="checkbox"><label for="user_misc_address_2"><input id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
116+
117+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street)
118+
end
119+
120+
test 'collection_check_boxes renders with checked option correctly with Proc :value_method' 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="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_address_1"><input checked="checked" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="checkbox"><label for="user_misc_address_2"><input id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
123+
124+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: "address_1")
125+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street, checked: collection.first)
126+
end
127+
128+
test 'collection_check_boxes renders with multiple checked options correctly with lambda :value_method' do
129+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
130+
expected = %{<input id="user_misc" multiple="multiple" name="user[misc][]" type="hidden" value="" /><div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="checkbox"><label for="user_misc_address_1"><input checked="checked" id="user_misc_address_1" name="user[misc][]" type="checkbox" value="address_1" /> Foo</label></div><div class="checkbox"><label for="user_misc_address_2"><input checked="checked" id="user_misc_address_2" name="user[misc][]" type="checkbox" value="address_2" /> Bar</label></div></div>}
131+
132+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: ["address_1", "address_2"])
133+
assert_equal expected, @builder.collection_check_boxes(:misc, collection, lambda { |a| "address_#{a.id}" }, :street, checked: collection)
134+
end
135+
136+
91137
end

test/bootstrap_radio_button_test.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,61 @@ def setup
6464

6565
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, :street, checked: 1)
6666
end
67+
68+
test 'collection_radio_buttons renders label defined by Proc correctly' do
69+
collection = [Address.new(id: 1, street: 'Foobar')]
70+
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" /> rabooF</label></div><span class="help-block">With a help!</span></div>}
71+
72+
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!')
73+
end
74+
75+
test 'collection_radio_buttons renders value defined by Proc correctly' do
76+
collection = [Address.new(id: 1, street: 'Foobar')]
77+
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_address_1"><input id="user_misc_address_1" name="user[misc]" type="radio" value="address_1" /> Foobar</label></div><span class="help-block">With a help!</span></div>}
78+
79+
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!')
80+
end
81+
82+
test 'collection_radio_buttons renders multiple radios with label defined by Proc correctly' do
83+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
84+
expected = %{<div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="radio"><label for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> ooF</label></div><div class="radio"><label for="user_misc_2"><input id="user_misc_2" name="user[misc]" type="radio" value="2" /> raB</label></div></div>}
85+
86+
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, Proc.new { |a| a.street.reverse })
87+
end
88+
89+
test 'collection_radio_buttons renders multiple radios with value defined by Proc correctly' do
90+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
91+
expected = %{<div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="radio"><label for="user_misc_address_1"><input id="user_misc_address_1" name="user[misc]" type="radio" value="address_1" /> Foo</label></div><div class="radio"><label for="user_misc_address_2"><input id="user_misc_address_2" name="user[misc]" type="radio" value="address_2" /> Bar</label></div></div>}
92+
93+
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, Proc.new { |a| "address_#{a.id}" }, :street)
94+
end
95+
96+
test 'collection_radio_buttons renders label defined by lambda correctly' do
97+
collection = [Address.new(id: 1, street: 'Foobar')]
98+
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" /> rabooF</label></div><span class="help-block">With a help!</span></div>}
99+
100+
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!')
101+
end
102+
103+
test 'collection_radio_buttons renders value defined by lambda correctly' do
104+
collection = [Address.new(id: 1, street: 'Foobar')]
105+
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_address_1"><input id="user_misc_address_1" name="user[misc]" type="radio" value="address_1" /> Foobar</label></div><span class="help-block">With a help!</span></div>}
106+
107+
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!')
108+
end
109+
110+
test 'collection_radio_buttons renders multiple radios with label defined by lambda correctly' do
111+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
112+
expected = %{<div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="radio"><label for="user_misc_1"><input id="user_misc_1" name="user[misc]" type="radio" value="1" /> ooF</label></div><div class="radio"><label for="user_misc_2"><input id="user_misc_2" name="user[misc]" type="radio" value="2" /> raB</label></div></div>}
113+
114+
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, :id, lambda { |a| a.street.reverse })
115+
end
116+
117+
test 'collection_radio_buttons renders multiple radios with value defined by lambda correctly' do
118+
collection = [Address.new(id: 1, street: 'Foo'), Address.new(id: 2, street: 'Bar')]
119+
expected = %{<div class="form-group"><label class="control-label" for="user_misc">Misc</label><div class="radio"><label for="user_misc_address_1"><input id="user_misc_address_1" name="user[misc]" type="radio" value="address_1" /> Foo</label></div><div class="radio"><label for="user_misc_address_2"><input id="user_misc_address_2" name="user[misc]" type="radio" value="address_2" /> Bar</label></div></div>}
120+
121+
assert_equal expected, @builder.collection_radio_buttons(:misc, collection, lambda { |a| "address_#{a.id}" }, :street)
122+
end
123+
67124
end

0 commit comments

Comments
 (0)