提交 9323fb60 编写于 作者: C Carlos Antonio da Silva

Create collection_radio_buttons helper

[Carlos Antonio da Silva + Rafael Mendonça França]
上级 3ccbc619
......@@ -191,6 +191,10 @@ def collection_select(object, method, collection, value_method, text_method, opt
Tags::CollectionSelect.new(object, method, self, collection, value_method, text_method, options, html_options).render
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 <tt><select></tt>, <tt><optgroup></tt> and <tt><option></tt> 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 without including <tt>:prompt</tt>
......
......@@ -4,27 +4,28 @@ module Tags #:nodoc:
extend ActiveSupport::Autoload
autoload :Base
autoload :CheckBox
autoload :CollectionRadioButtons
autoload :CollectionSelect
autoload :DateSelect
autoload :DatetimeSelect
autoload :EmailField
autoload :FileField
autoload :GroupedCollectionSelect
autoload :HiddenField
autoload :Label
autoload :TextField
autoload :NumberField
autoload :PasswordField
autoload :HiddenField
autoload :FileField
autoload :RadioButton
autoload :RangeField
autoload :SearchField
autoload :Select
autoload :TelField
autoload :UrlField
autoload :EmailField
autoload :NumberField
autoload :RangeField
autoload :TextArea
autoload :CheckBox
autoload :RadioButton
autoload :Select
autoload :CollectionSelect
autoload :GroupedCollectionSelect
autoload :TimeZoneSelect
autoload :DateSelect
autoload :TextField
autoload :TimeSelect
autoload :DatetimeSelect
autoload :TimeZoneSelect
autoload :UrlField
end
end
end
module ActionView
module Helpers
module Tags
class CollectionRadioButtons < CollectionSelect
delegate :radio_button, :label, :to => :@template_object
def render
rendered_collection = render_collection(
@method_name, @collection, @value_method, @text_method, @options, @html_options
) do |value, text, default_html_options|
if block_given?
yield sanitize_attribute_name(@method_name, value), text, value, default_html_options
else
radio_button(@object_name, @method_name, value, default_html_options) +
label(@object_name, sanitize_attribute_name(@method_name, value), text, :class => "collection_radio_buttons")
end
end
wrap_rendered_collection(rendered_collection, @options)
end
private
# Generate default options for collection helpers, such as :checked and
# :disabled.
def default_html_options_for_collection(item, value, options, html_options) #:nodoc:
html_options = html_options.dup
[:checked, :selected, :disabled].each do |option|
next unless options[option]
accept = if options[option].respond_to?(:call)
options[option].call(item)
else
Array(options[option]).include?(value)
end
if accept
html_options[option] = true
elsif option == :checked
html_options[option] = false
end
end
html_options
end
def sanitize_attribute_name(attribute, value) #:nodoc:
"#{attribute}_#{value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase}"
end
def render_collection(attribute, collection, value_method, text_method, options={}, html_options={}) #:nodoc:
item_wrapper_tag = options.fetch(:item_wrapper_tag, :span)
item_wrapper_class = options[:item_wrapper_class]
collection.map do |item|
value = value_for_collection(item, value_method)
text = value_for_collection(item, text_method)
default_html_options = default_html_options_for_collection(item, value, options, html_options)
rendered_item = yield value, text, default_html_options
item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, :class => item_wrapper_class) : rendered_item
end.join.html_safe
end
def value_for_collection(item, value) #:nodoc:
value.respond_to?(:call) ? value.call(item) : item.send(value)
end
def wrap_rendered_collection(collection, options)
wrapper_tag = options[:collection_wrapper_tag]
if wrapper_tag
wrapper_class = options[:collection_wrapper_class]
@template_object.content_tag(wrapper_tag, collection, :class => wrapper_class)
else
collection
end
end
end
end
end
end
require 'abstract_unit'
class FormCollectionsHelperTest < ActionView::TestCase
def assert_no_select(selector, value = nil)
assert_select(selector, :text => value, :count => 0)
end
def with_collection_radio_buttons(*args, &block)
concat collection_radio_buttons(*args, &block)
end
# COLLECTION RADIO
test 'collection radio accepts a collection and generate inputs from value method' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
assert_select 'input[type=radio][value=true]#user_active_true'
assert_select 'input[type=radio][value=false]#user_active_false'
end
test 'collection radio accepts a collection and generate inputs from label method' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
assert_select 'label.collection_radio_buttons[for=user_active_true]', 'true'
assert_select 'label.collection_radio_buttons[for=user_active_false]', 'false'
end
test 'collection radio handles camelized collection values for labels correctly' do
with_collection_radio_buttons :user, :active, ['Yes', 'No'], :to_s, :to_s
assert_select 'label.collection_radio_buttons[for=user_active_yes]', 'Yes'
assert_select 'label.collection_radio_buttons[for=user_active_no]', 'No'
end
test 'colection radio should sanitize collection values for labels correctly' do
with_collection_radio_buttons :user, :name, ['$0.99', '$1.99'], :to_s, :to_s
assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
end
test 'collection radio accepts checked item' do
with_collection_radio_buttons :user, :active, [[1, true], [0, false]], :last, :first, :checked => true
assert_select 'input[type=radio][value=true][checked=checked]'
assert_no_select 'input[type=radio][value=false][checked=checked]'
end
test 'collection radio accepts multiple disabled items' do
collection = [[1, true], [0, false], [2, 'other']]
with_collection_radio_buttons :user, :active, collection, :last, :first, :disabled => [true, false]
assert_select 'input[type=radio][value=true][disabled=disabled]'
assert_select 'input[type=radio][value=false][disabled=disabled]'
assert_no_select 'input[type=radio][value=other][disabled=disabled]'
end
test 'collection radio accepts single disable item' do
collection = [[1, true], [0, false]]
with_collection_radio_buttons :user, :active, collection, :last, :first, :disabled => true
assert_select 'input[type=radio][value=true][disabled=disabled]'
assert_no_select 'input[type=radio][value=false][disabled=disabled]'
end
test 'collection radio accepts html options as input' do
collection = [[1, true], [0, false]]
with_collection_radio_buttons :user, :active, collection, :last, :first, {}, :class => 'special-radio'
assert_select 'input[type=radio][value=true].special-radio#user_active_true'
assert_select 'input[type=radio][value=false].special-radio#user_active_false'
end
test 'collection radio wraps the collection in the given collection wrapper tag' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
assert_select 'ul input[type=radio]', :count => 2
end
test 'collection radio does not render any wrapper tag by default' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
assert_select 'input[type=radio]', :count => 2
assert_no_select 'ul'
end
test 'collection radio does not wrap the collection when given falsy values' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
assert_select 'input[type=radio]', :count => 2
assert_no_select 'ul'
end
test 'collection radio uses the given class for collection wrapper tag' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s,
:collection_wrapper_tag => :ul, :collection_wrapper_class => "items-list"
assert_select 'ul.items-list input[type=radio]', :count => 2
end
test 'collection radio uses no class for collection wrapper tag when no wrapper tag is given' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s,
:collection_wrapper_class => "items-list"
assert_select 'input[type=radio]', :count => 2
assert_no_select 'ul'
assert_no_select '.items-list'
end
test 'collection radio uses no class for collection wrapper tag by default' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
assert_select 'ul'
assert_no_select 'ul[class]'
end
test 'collection radio wrap items in a span tag by default' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
assert_select 'span input[type=radio][value=true]#user_active_true + label'
assert_select 'span input[type=radio][value=false]#user_active_false + label'
end
test 'collection radio wraps each item in the given item wrapper tag' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
assert_select 'li input[type=radio]', :count => 2
end
test 'collection radio does not wrap each item when given explicitly falsy value' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => false
assert_select 'input[type=radio]'
assert_no_select 'span input[type=radio]'
end
test 'collection radio uses the given class for item wrapper tag' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s,
:item_wrapper_tag => :li, :item_wrapper_class => "inline"
assert_select "li.inline input[type=radio]", :count => 2
end
test 'collection radio uses no class for item wrapper tag when no wrapper tag is given' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s,
:item_wrapper_tag => nil, :item_wrapper_class => "inline"
assert_select 'input[type=radio]', :count => 2
assert_no_select 'li'
assert_no_select '.inline'
end
test 'collection radio uses no class for item wrapper tag by default' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s,
:item_wrapper_tag => :li
assert_select "li", :count => 2
assert_no_select "li[class]"
end
test 'collection radio does not wrap input inside the label' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
assert_select 'input[type=radio] + label'
assert_no_select 'label input'
end
test 'collection radio accepts a block to render the radio and label as required' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |label_for, text, value, html_options|
concat label(:user, label_for, text) { radio_button(:user, :active, value, html_options) }
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
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册