require 'cgi'
require 'erb'
require File.dirname(__FILE__) + '/form_helper'
module ActionView
module Helpers
# Provides a number of methods for turning different kinds of containers into a set of option tags. Neither of the methods provide
# the actual select tag, so you'll need to construct that in HTML manually.
module FormOptionsHelper
include ERB::Util
def select(object, method, choices, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_select_tag(choices, options, html_options)
end
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_collection_select_tag(collection, value_method, text_method, options, html_options)
end
def country_select(object, method, priority_countries = nil, options = {}, html_options = {})
InstanceTag.new(object, method, self).to_country_select_tag(priority_countries, options, html_options)
end
# Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
# where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
# the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values
# become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +Selected+
# may also be an array of values to be selected when using a multiple select.
#
# Examples (call, result):
# options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
# \n
#
# options_for_select([ "VISA", "Mastercard" ], "Mastercard")
# \n
#
# options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
# \n
#
# options_for_select([ "VISA", "Mastercard", "Discover" ], ["VISA", "Discover"])
# \n\n
def options_for_select(container, selected = nil)
container = container.to_a if Hash === container
options_for_select = container.inject([]) do |options, element|
if element.respond_to?(:first) && element.respond_to?(:last)
is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element.last) : element.last == selected) )
if is_selected
options << ""
else
options << ""
end
else
is_selected = ( (selected.respond_to?(:include?) ? selected.include?(element) : element == selected) )
options << ((is_selected) ? "" : "")
end
end
options_for_select.join("\n")
end
# Returns a string of option tags that has been compiled by iterating over the +collection+ and assigning the
# the result of a call to the +value_method+ as the option value and the +text_method+ as the option text.
# If +selected_value+ is specified, the element returning a match on +value_method+ will get the selected option tag.
#
# Example (call, result). Imagine a loop iterating over each +person+ in @project.people to generate a input tag:
# options_from_collection_for_select(@project.people, "id", "name")
#
def options_from_collection_for_select(collection, value_method, text_method, selected_value = nil)
options_for_select(
collection.inject([]) { |options, object| options << [ object.send(text_method), object.send(value_method) ] },
selected_value
)
end
# Returns a string of option tags, like options_from_collection_for_select, but surrounds them by