Skip to content

Commit

Permalink
Allow collection helpers with block to access current object in the c…
Browse files Browse the repository at this point in the history
…ollection

This gives a lot more flexibility to the user, for instance to generate
a collection of check boxes and labels, allowing to add custom classes
or data-* attributes to the label/check_box using another object
attribute.

This basically mimics options_for_select functionality that accepts a
third option for each item to generate html attributes for each option.
  • Loading branch information
carlosantoniodasilva committed Feb 14, 2012
1 parent 11d1bdc commit a10ed70
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 9 deletions.
Expand Up @@ -14,9 +14,9 @@ def check_box(extra_html_options={})
end

def render
rendered_collection = render_collection do |value, text, default_html_options|
rendered_collection = render_collection do |item, value, text, default_html_options|
default_html_options[:multiple] = true
builder = instantiate_builder(CheckBoxBuilder, value, text, default_html_options)
builder = instantiate_builder(CheckBoxBuilder, item, value, text, default_html_options)

if block_given?
yield builder
Expand Down
11 changes: 6 additions & 5 deletions actionpack/lib/action_view/helpers/tags/collection_helpers.rb
Expand Up @@ -3,13 +3,14 @@ module Helpers
module Tags
module CollectionHelpers
class Builder
attr_reader :text, :value
attr_reader :object, :text, :value

def initialize(template_object, object_name, method_name,
def initialize(template_object, object_name, method_name, object,
sanitized_attribute_name, text, value, input_html_options)
@template_object = template_object
@object_name = object_name
@method_name = method_name
@object = object
@sanitized_attribute_name = sanitized_attribute_name
@text = text
@value = value
Expand All @@ -32,8 +33,8 @@ def initialize(object_name, method_name, template_object, collection, value_meth

private

def instantiate_builder(builder_class, value, text, html_options)
builder_class.new(@template_object, @object_name, @method_name,
def instantiate_builder(builder_class, item, value, text, html_options)
builder_class.new(@template_object, @object_name, @method_name, item,
sanitize_attribute_name(value), text, value, html_options)
end

Expand Down Expand Up @@ -71,7 +72,7 @@ def render_collection #:nodoc:
text = value_for_collection(item, @text_method)
default_html_options = default_html_options_for_collection(item, value)

yield value, text, default_html_options
yield item, value, text, default_html_options
end.join.html_safe
end
end
Expand Down
Expand Up @@ -14,8 +14,8 @@ def radio_button(extra_html_options={})
end

def render
render_collection do |value, text, default_html_options|
builder = instantiate_builder(RadioButtonBuilder, value, text, default_html_options)
render_collection do |item, value, text, default_html_options|
builder = instantiate_builder(RadioButtonBuilder, item, value, text, default_html_options)

if block_given?
yield builder
Expand Down
26 changes: 26 additions & 0 deletions actionpack/test/template/form_collections_helper_test.rb
Expand Up @@ -123,6 +123,19 @@ def with_collection_check_boxes(*args, &block)
end
end

test 'collection radio with block helpers allows access to the current object item in the collection to access extra properties' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
b.label(:class => b.object) { b.radio_button + b.text }
end

assert_select 'label.true[for=user_active_true]', 'true' do
assert_select 'input#user_active_true[type=radio]'
end
assert_select 'label.false[for=user_active_false]', 'false' do
assert_select 'input#user_active_false[type=radio]'
end
end

test 'collection radio buttons with fields for' do
collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
@output_buffer = fields_for(:post) do |p|
Expand Down Expand Up @@ -298,4 +311,17 @@ def with_collection_check_boxes(*args, &block)
assert_select 'input#user_active_false[type=checkbox]'
end
end

test 'collection check boxes with block helpers allows access to the current object item in the collection to access extra properties' do
with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
b.label(:class => b.object) { b.check_box + b.text }
end

assert_select 'label.true[for=user_active_true]', 'true' do
assert_select 'input#user_active_true[type=checkbox]'
end
assert_select 'label.false[for=user_active_false]', 'false' do
assert_select 'input#user_active_false[type=checkbox]'
end
end
end

0 comments on commit a10ed70

Please sign in to comment.