Skip to content

Commit

Permalink
Add changelog, docs and guides entries
Browse files Browse the repository at this point in the history
[Carlos Antonio da Silva + Rafael Mendonça França]
  • Loading branch information
carlosantoniodasilva authored and rafaelfranca committed Feb 2, 2012
1 parent 9035324 commit f506c80
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 20 deletions.
38 changes: 37 additions & 1 deletion actionpack/CHANGELOG.md
@@ -1,13 +1,49 @@
## Rails 4.0.0 (unreleased) ##

* Allow `value_method` and `text_method` arguments from `collection_select` and
`options_from_collection_for_select` to receive an object that responds to `:call`,
such as a `proc`, to evaluate the option in the current element context. This works
the same way with `collection_radio_buttons` and `collection_check_boxes`.

*Carlos Antonio da Silva + Rafael Mendonça França*

* Add `collection_check_boxes` form helper, similar to `collection_select`:
Example:

collection_check_boxes :post, :author_ids, Author.all, :id, :name
# Outputs something like:
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" />
<label class="collection_check_boxes" for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label class="collection_check_boxes" for="post_author_ids_2">D. Thomas</label>
<input name="post[author_ids][]" type="hidden" value="" />

The label/check_box pairs can be customized with a block.

*Carlos Antonio da Silva + Rafael Mendonça França*

* Add `collection_radio_buttons` form helper, similar to `collection_select`:
Example:

collection_radio_buttons :post, :author_id, Author.all, :id, :name
# Outputs something like:
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" />
<label class="collection_radio_buttons" for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label class="collection_radio_buttons" for="post_author_id_2">D. Thomas</label>

The label/radio_button pairs can be customized with a block.

*Carlos Antonio da Silva + Rafael Mendonça França*

* check_box with `:form` html5 attribute will now replicate the `:form`
attribute to the hidden field as well. *Carlos Antonio da Silva*

* `label` form helper accepts :for => nil to not generate the attribute. *Carlos Antonio da Silva*

* Add `:format` option to number_to_percentage *Rodrigo Flores*

* Add `config.action_view.logger` to configure logger for ActionView. *Rafael França*
* Add `config.action_view.logger` to configure logger for ActionView. *Rafael Mendonça França*

* Deprecated ActionController::Integration in favour of ActionDispatch::Integration

Expand Down
80 changes: 63 additions & 17 deletions actionpack/lib/action_view/helpers/form_options_helper.rb
Expand Up @@ -164,7 +164,9 @@ def select(object, method, choices, options = {}, html_options = {})
#
# The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are methods to be called on each member
# of +collection+. The return values are used as the +value+ attribute and contents of each
# <tt><option></tt> tag, respectively.
# <tt><option></tt> tag, respectively. They can also be any object that responds to +call+, such
# as a +proc+, that will be called for each member of the +collection+ to
# retrieve the value/text.
#
# Example object structure for use with this method:
# class Post < ActiveRecord::Base
Expand Down Expand Up @@ -520,13 +522,17 @@ def time_zone_options_for_select(selected = nil, priority_zones = nil, model = :
zone_options.html_safe
end

# Returns radio button tags for the collection of existing return values of +method+ for
# +object+'s class. The value returned from calling +method+ on the instance +object+ will
# be selected. If calling +method+ returns +nil+, no selection is made.
# Returns radio button tags for the collection of existing return values
# of +method+ for +object+'s class. The value returned from calling
# +method+ on the instance +object+ will be selected. If calling +method+
# returns +nil+, no selection is made.
#
# The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are methods to be called on each member
# of +collection+. The return values are used as the +value+ attribute and contents of each
# radio button tag, respectively.
# The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are
# methods to be called on each member of +collection+. The return values
# are used as the +value+ attribute and contents of each radio button tag,
# respectively. They can also be any object that responds to +call+, such
# as a +proc+, that will be called for each member of the +collection+ to
# retrieve the value/text.
#
# Example object structure for use with this method:
# class Post < ActiveRecord::Base
Expand All @@ -549,24 +555,46 @@ def time_zone_options_for_select(selected = nil, priority_zones = nil, model = :
# <label class="collection_radio_buttons" for="post_author_id_2">D. Thomas</label>
# <input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
# <label class="collection_radio_buttons" for="post_author_id_3">M. Clark</label>
#
# It is also possible to customize the way the elements will be shown by
# giving a block to the method:
# collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
# b.label { b.radio_button }
# end
#
# The argument passed to the block is a special kind of builder for this
# collection, which has the ability to generate the label and radio button
# for the current item in the collection, with proper text and value.
# Using it, you can change the label and radio button display order or
# even use the label as wrapper, as in the example above.
#
# The builder methods <tt>label</tt> and <tt>radio_button</tt> also accept
# extra html options:
# collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
# b.label(:class => "radio_button") { b.radio_button(:class => "radio_button") }
# end
def collection_radio_buttons(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
Tags::CollectionRadioButtons.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end

# Returns check box tags for the collection of existing return values of +method+ # for
# +object+'s class. The value returned from calling +method+ on the instance +object+ will
# be selected. If calling +method+ returns +nil+, no selection is made.
# Returns check box tags for the collection of existing return values of
# +method+ for +object+'s class. The value returned from calling +method+
# on the instance +object+ will be selected. If calling +method+ returns
# +nil+, no selection is made.
#
# The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are methods to be called on each member
# of +collection+. The return values are used as the +value+ attribute and contents of each
# check box tag, respectively.
# The <tt>:value_method</tt> and <tt>:text_method</tt> parameters are
# methods to be called on each member of +collection+. The return values
# are used as the +value+ attribute and contents of each check box tag,
# respectively. They can also be any object that responds to +call+, such
# as a +proc+, that will be called for each member of the +collection+ to
# retrieve the value/text.
#
# Example object structure for use with this method:
# class Post < ActiveRecord::Base
# has_and_belongs_to :author
# has_and_belongs_to_many :author
# end
# class Author < ActiveRecord::Base
# has_and_belongs_to :posts
# has_and_belongs_to_many :posts
# def name_with_initial
# "#{first_name.first}. #{last_name}"
# end
Expand All @@ -578,11 +606,29 @@ def collection_radio_buttons(object, method, collection, value_method, text_meth
# If <tt>@post.author_ids</tt> is already <tt>[1]</tt>, this would return:
# <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
# <label class="collection_check_boxes" for="post_author_ids_1">D. Heinemeier Hansson</label>
# <input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="2" />
# <label class="collection_check_boxes" for="post_author_ids_1">D. Thomas</label>
# <input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
# <label class="collection_check_boxes" for="post_author_ids_2">D. Thomas</label>
# <input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
# <label class="collection_check_boxes" for="post_author_ids_3">M. Clark</label>
# <input name="post[author_ids][]" type="hidden" value="" />
#
# It is also possible to customize the way the elements will be shown by
# giving a block to the method:
# collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
# b.label { b.check_box }
# end
#
# The argument passed to the block is a special kind of builder for this
# collection, which has the ability to generate the label and check box
# for the current item in the collection, with proper text and value.
# Using it, you can change the label and check box display order or even
# use the label as wrapper, as in the example above.
#
# The builder methods <tt>label</tt> and <tt>check_box</tt> also accept
# extra html options:
# collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
# b.label(:class => "check_box") { b.check_box(:class => "check_box") }
# end
def collection_check_boxes(object, method, collection, value_method, text_method, options = {}, html_options = {}, &block)
Tags::CollectionCheckBoxes.new(object, method, self, collection, value_method, text_method, options, html_options).render(&block)
end
Expand Down
22 changes: 20 additions & 2 deletions actionpack/test/template/form_collections_helper_test.rb
Expand Up @@ -83,7 +83,7 @@ def with_collection_check_boxes(*args, &block)
assert_no_select 'label input'
end

test 'collection radio accepts a block to render the radio and label as required' do
test 'collection radio accepts a block to render the label as radio button wrapper' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
b.label { b.radio_button }
end
Expand All @@ -92,6 +92,15 @@ def with_collection_check_boxes(*args, &block)
assert_select 'label[for=user_active_false] > input#user_active_false[type=radio]'
end

test 'collection radio accepts a block to change the order of label and radio button' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
b.label + b.radio_button
end

assert_select 'label[for=user_active_true] + input#user_active_true[type=radio]'
assert_select 'label[for=user_active_false] + input#user_active_false[type=radio]'
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 @@ -228,12 +237,21 @@ def with_collection_check_boxes(*args, &block)
assert_no_select 'label input'
end

test 'collection check boxes accepts a block to render the radio and label as required' do
test 'collection check boxes accepts a block to render the label as check box wrapper' do
with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
b.label { b.check_box }
end

assert_select 'label[for=user_active_true] > input#user_active_true[type=checkbox]'
assert_select 'label[for=user_active_false] > input#user_active_false[type=checkbox]'
end

test 'collection check boxes accepts a block to change the order of label and check box' do
with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
b.label + b.check_box
end

assert_select 'label[for=user_active_true] + input#user_active_true[type=checkbox]'
assert_select 'label[for=user_active_false] + input#user_active_false[type=checkbox]'
end
end
73 changes: 73 additions & 0 deletions railties/guides/source/action_view_overview.textile
Expand Up @@ -1124,6 +1124,79 @@ If <tt>@post.author_id</tt> is 1, this would return:
</select>
</html>

h5. collection_radio_buttons

Returns +radio_button+ tags for the collection of existing return values of +method+ for +object+'s class.

Example object structure for use with this method:

<ruby>
class Post < ActiveRecord::Base
belongs_to :author
end

class Author < ActiveRecord::Base
has_many :posts
def name_with_initial
"#{first_name.first}. #{last_name}"
end
end
</ruby>

Sample usage (selecting the associated Author for an instance of Post, +@post+):

<ruby>
collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial)
</ruby>

If <tt>@post.author_id</tt> is 1, this would return:

<html>
<input id="post_author_id_1" name="post[author_id]" type="radio" value="1" checked="checked" />
<label class="collection_radio_buttons" for="post_author_id_1">D. Heinemeier Hansson</label>
<input id="post_author_id_2" name="post[author_id]" type="radio" value="2" />
<label class="collection_radio_buttons" for="post_author_id_2">D. Thomas</label>
<input id="post_author_id_3" name="post[author_id]" type="radio" value="3" />
<label class="collection_radio_buttons" for="post_author_id_3">M. Clark</label>
</html>

h5. collection_check_boxes

Returns +check_box+ tags for the collection of existing return values of +method+ for +object+'s class.

Example object structure for use with this method:

<ruby>
class Post < ActiveRecord::Base
has_and_belongs_to_many :author
end

class Author < ActiveRecord::Base
has_and_belongs_to_many :posts
def name_with_initial
"#{first_name.first}. #{last_name}"
end
end
</ruby>

Sample usage (selecting the associated Authors for an instance of Post, +@post+):

<ruby>
collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial)
</ruby>

If <tt>@post.author_ids</tt> is [1], this would return:

<html>
<input id="post_author_ids_1" name="post[author_ids][]" type="checkbox" value="1" checked="checked" />
<label class="collection_check_boxes" for="post_author_ids_1">D. Heinemeier Hansson</label>
<input id="post_author_ids_2" name="post[author_ids][]" type="checkbox" value="2" />
<label class="collection_check_boxes" for="post_author_ids_2">D. Thomas</label>
<input id="post_author_ids_3" name="post[author_ids][]" type="checkbox" value="3" />
<label class="collection_check_boxes" for="post_author_ids_3">M. Clark</label>
<input name="post[author_ids][]" type="hidden" value="" />
</html>

h5. country_options_for_select

Returns a string of option tags for pretty much any country in the world.
Expand Down

0 comments on commit f506c80

Please sign in to comment.