Created
July 14, 2010 12:46
-
-
Save ernie/475368 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActionView | |
module Helpers | |
class FormBuilder | |
Check = Struct.new(:box, :label) | |
# Behaves almost exactly like the select method, but instead of generating a select tag, | |
# generates Checks. These consist of two attributes, +box+ and +label+, | |
# which are (unsurprisingly) the HTML for the check box and the label. Called without a block, | |
# this method will return an array of check boxes. Called with a block, it will yield each | |
# check box to your template. | |
# | |
# *Parameters:* | |
# | |
# * +method+ - The method name on the form_for object | |
# * +choices+ - An array of arrays, the first value in each element is the text for the | |
# label, and the last is the value for the checkbox | |
# * +options+ - An options hash to be passed through to the checkboxes | |
# | |
# *Examples:* | |
# | |
# <b>Simple formatting:</b> | |
# | |
# <h4>How many heads?</h4> | |
# <ul> | |
# <% f.check_boxes :number_of_heads_in, | |
# [['One', 1], ['Two', 2], ['Three', 3]], :class => 'checkboxy' do |check| %> | |
# <li> | |
# <%= check.box %> | |
# <%= check.label %> | |
# </li> | |
# <% end %> | |
# </ul> | |
# | |
# This example will output the checkboxes and labels in an unordered list format. | |
# | |
# <b>Grouping:</b> | |
# | |
# Chain <tt>in_groups_of(<num>, false)</tt> on check_boxes like so: | |
# <h4>How many heads?</h4> | |
# <p> | |
# <% f.check_boxes(:number_of_heads_in, | |
# [['One', 1], ['Two', 2], ['Three', 3]], | |
# :class => 'checkboxy').in_groups_of(2, false) do |checks| %> | |
# <% checks.each do |check| %> | |
# <%= check.box %> | |
# <%= check.label %> | |
# <% end %> | |
# <br /> | |
# <% end %> | |
# </p> | |
def check_boxes(method, choices = [], options = {}, &block) | |
unless choices.first.respond_to?(:first) && choices.first.respond_to?(:last) | |
raise ArgumentError, 'invalid choice array specified' | |
end | |
collection_check_boxes(method, choices, :last, :first, options, &block) | |
end | |
# Just like +check_boxes+, but this time you can pass in a collection, value, and text method, | |
# as with collection_select. | |
# | |
# Example: | |
# | |
# <% f.collection_check_boxes :head_sizes_in, HeadSize.all, | |
# :id, :name, :class => 'headcheck' do |check| %> | |
# <%= check.box %> <%= check.label %> | |
# <% end %> | |
def collection_check_boxes(method, collection, value_method, text_method, options = {}, &block) | |
check_boxes = [] | |
collection.each do |choice| | |
text = choice.send(text_method) | |
value = choice.send(value_method) | |
check = Check.new | |
check.box = @template.check_box_tag( | |
"#{@object_name}[#{method}][]", | |
value, | |
[@object.send(method)].flatten.include?(value), | |
options.merge(:id => [@object_name, method.to_s, value.to_s.underscore].join('_')) | |
) | |
check.label = @template.label_tag([@object_name, method.to_s, value.to_s.underscore].join('_'), | |
text) | |
if block_given? | |
yield check | |
else | |
check_boxes << check | |
end | |
end | |
check_boxes unless block_given? | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment