module ActionView::Helpers::FormOptionsHelper
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_collection_select_tag(collection, value_method, text_method, options, html_options) end
def extract_selected_and_disabled(selected)
def extract_selected_and_disabled(selected) if selected.is_a?(Proc) [ selected, nil ] else selected = Array.wrap(selected) options = selected.extract_options!.symbolize_keys [ options.include?(:selected) ? options[:selected] : selected, options[:disabled] ] end end
def extract_values_from_collection(collection, value_method, selected)
def extract_values_from_collection(collection, value_method, selected) if selected.is_a?(Proc) collection.map do |element| element.send(value_method) if selected.call(element) end.compact else selected end end
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
def grouped_collection_select(object, method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_grouped_collection_select_tag(collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options) end
def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)
Note: Only the
Possible output:
grouped_options_for_select(grouped_options)
}
'Europe' => ['Denmark','Germany','France']
'North America' => [['United States','US], 'Canada'],
grouped_options = {
Sample usage (Hash):
grouped_options_for_select(grouped_options)
]
['Denmark','Germany','France']]
['Europe',
[['United States','US'],'Canada']],
['North America',
grouped_options = [
Sample usage (Array):
prepends an option with a generic prompt - "Please select" - or the given prompt string.
* +prompt+ - set to true or a prompt string. When the select element doesn't have a value yet, this
as you might have the same option in multiple groups. Each will then get selected="selected".
which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
* +selected_key+ - A value equal to the +value+ attribute for one of the tags,
Ex. ["North America",[["United States","US"],["Canada","CA"]]]
nested array of text-value pairs. See options_for_select for more info.
* +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
Parameters:
wraps them with
Returns a string of tags, like options_for_select, but
def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil) body = '' body << content_tag(:option, prompt, { :value => "" }, true) if prompt grouped_options = grouped_options.sort if grouped_options.is_a?(Hash) grouped_options.each do |group| body << content_tag(:optgroup, options_for_select(group[1], selected_key), :label => group[0]) end body.html_safe end
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
Note: Only the
...
...
Possible output:
option_groups_from_collection_for_select(@continents, :countries, :name, :id, :name, 3)
Sample usage:
end
# attribs: id, name, continent_id
belongs_to :continent
class Country < ActiveRecord::Base
end
# attribs: id, name
has_many :countries
class Continent < ActiveRecord::Base
Example object structure for use with this method:
to be specified.
to +option_key_method+. If +nil+, no selection is made. Can also be a hash if disabled values are
which will have the +selected+ attribute set. Corresponds to the return value of one of the calls
* +selected_key+ - A value equal to the +value+ attribute for one of the tags,
+collection+, returns a value to be used as the contents of its tag.
* +option_value_method+ - The name of a method which, when called on a child object of a member of
+collection+, returns a value to be used as the +value+ attribute for its tag.
* +option_key_method+ - The name of a method which, when called on a child object of a member of
string to be used as the +label+ attribute for its
* group_label_method+ - The name of a method which, when called on a member of +collection+, returns a
array of child objects representing the tags.
* +group_method+ - The name of a method which, when called on a member of +collection+, returns an
* +collection+ - An array of objects representing the
Parameters:
groups them by
Returns a string of tags, like options_from_collection_for_select, but
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil) collection.map do |group| group_label_string = eval("group.#{group_label_method}") "<optgroup label=\"#{html_escape(group_label_string)}\">" + options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) + '</optgroup>' end.join.html_safe end
def option_html_attributes(element)
def option_html_attributes(element) return "" unless Array === element html_attributes = [] element.select { |e| Hash === e }.reduce({}, :merge).each do |k, v| html_attributes << " #{k}=\"#{html_escape(v.to_s)}\"" end html_attributes.join end
def option_text_and_value(option)
def option_text_and_value(option) # Options are [text, value] pairs or strings used for both. case when Array === option option = option.reject { |e| Hash === e } [option.first, option.last] when !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last) [option.first, option.last] else [option, option] end end
def option_value_selected?(value, selected)
def option_value_selected?(value, selected) if selected.respond_to?(:include?) && !selected.is_a?(String) selected.include? value else value == selected end end
def options_for_select(container, selected = nil)
\n\n\n
options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :selected => "Free", :disabled => "Super Platinum")
\n\n\n
options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => ["Advanced", "Super Platinum"])
\n\n\n
options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => "Super Platinum")
Examples:
or array of values to be disabled. In this case, you can use :selected to specify selected option tags.
If you wish to specify disabled option tags, set +selected+ to be a hash, with :disabled being either a value
\n
options_for_select([["Dollar", "$", {:class=>"bold"}], ["Kroner", "DKK", {:onclick => "alert('HI');"}]])
\n\n
options_for_select([ "Denmark", ["USA", {:class=>'bold'}], "Sweden" ], ["USA", "Sweden"])
Examples:
You can optionally provide html attributes as the last element of the array.
\n\n
options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
\n
options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
\n
options_for_select([ "VISA", "MasterCard" ], "MasterCard")
\n
options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
Examples (call, result):
may also be an array of values to be selected when using a multiple select.
become lasts. If +selected+ is specified, the matching "last" or element will get the selected option-tag. +selected+
the "firsts" as option text. Hashes are turned into this form automatically, so the keys become "firsts" and values
where the elements respond to first and last (such as a two-element array), the "lasts" serve as option values and
Accepts a container (hash, array, enumerable, your type) and returns a string of option tags. Given a container
def options_for_select(container, selected = nil) return container if String === container container = container.to_a if Hash === container selected, disabled = extract_selected_and_disabled(selected).map do | r | Array.wrap(r).map(&:to_s) end container.map do |element| html_attributes = option_html_attributes(element) text, value = option_text_and_value(element).map(&:to_s) selected_attribute = ' selected="selected"' if option_value_selected?(value, selected) disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled) %(<option value="#{html_escape(value)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text)}</option>) end.join("\n").html_safe end
def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
options_from_collection_for_select(@people, 'id', 'name', 1)
Will not select a person with the id of 1 because 1 (an Integer) is not the same as '1' (a string)
options_from_collection_for_select(@people, 'id', 'name', '1')
Failure to do this will produce undesired results. Example:
Be sure to specify the same class as the +value_method+ when specifying selected or disabled options.
+selected+ can also be a hash, specifying both :selected and/or :disabled values as required.
function are the selected values.
If +selected+ is specified as a Proc, those members of the collection that return true for the anonymous
will be selected option tag(s).
If +selected+ is specified as a value or array of values, the element(s) returning a match on +value_method+
select_tag 'person', options_from_collection_for_select(@people, 'id', 'name')
This is more often than not used inside a #select_tag like this example:
This will output the same HTML as if you did this:
options_from_collection_for_select(@people, 'id', 'name')
Example:
the result of a call to the +value_method+ as the option value and the +text_method+ as the option text.
Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
def options_from_collection_for_select(collection, value_method, text_method, selected = nil) options = collection.map do |element| [element.send(text_method), element.send(value_method)] end selected, disabled = extract_selected_and_disabled(selected) select_deselect = {} select_deselect[:selected] = extract_values_from_collection(collection, value_method, selected) select_deselect[:disabled] = extract_values_from_collection(collection, value_method, disabled) options_for_select(options, select_deselect) end
def select(object, method, choices, options = {}, html_options = {})
or :selected => nil to leave all options unselected. Similarly, you can specify values to be disabled in the option
By default, post.person_id is the selected option. Specify :selected => value to use a different selection
In addition, this allows a single partial to be used to generate form inputs for both edit and create forms.
This allows the user to submit a form page more than once with the expected results of creating multiple records.
to the database. Instead, a second model object is created when the create request is received.
new model instance is assigned the default options and bound to @model_name. Usually this model is not saved
This can be used to provide a default set of options in the standard way: before rendering the create form, a
could become:
select("post", "person_id", Person.all.collect {|p| [ p.name, p.id ] }, { :include_blank => true })
Example with @post.person_id => 1:
See options_for_select for the required format of the choices parameter.
The option currently held by the object will be selected, provided that the object is available.
Create a select tag and a series of contained option tags for the provided object and method.
def select(object, method, choices, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_select_tag(choices, options, html_options) end
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone)
NOTE: Only the option tags are returned, you have to wrap this call in
returns an array of objects that represent time zones.
is that the +model+ parameter be an object that responds to +all+, and
be obtained in Active Record as a value object). The only requirement
By default, +model+ is the ActiveSupport::TimeZone constant (which can
a ActiveSupport::TimeZone.
The +selected+ parameter must be either +nil+, or a string that names
of the US time zones, or a Regexp to select the zones of your choice)
ActiveSupport::TimeZone.us_zones as a convenience for obtaining a list
be listed above the rest of the (long) list. (You can use
ActiveSupport::TimeZone objects as +priority_zones+, so that they will
marked as the selected option tag. You can also supply an array of
world. Supply a ActiveSupport::TimeZone name as +selected+ to have it
Returns a string of option tags for pretty much any time zone in the
def time_zone_options_for_select(selected = nil, priority_zones = nil, model = ::ActiveSupport::TimeZone) zone_options = "" zones = model.all convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } } if priority_zones if priority_zones.is_a?(Regexp) priority_zones = model.all.find_all {|z| z =~ priority_zones} end zone_options += options_for_select(convert_zones[priority_zones], selected) zone_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n" zones = zones.reject { |z| priority_zones.include?( z ) } end zone_options += options_for_select(convert_zones[zones], selected) zone_options.html_safe end
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
time_zone_select( "user", 'time_zone', /Australia/)
time_zone_select( "user", 'time_zone', [ ActiveSupport::TimeZone['Alaska'], ActiveSupport::TimeZone['Hawaii'] ])
time_zone_select( "user", 'time_zone', ActiveSupport::TimeZone.us_zones, :default => "Pacific Time (US & Canada)")
time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )
time_zone_select( "user", "time_zone", nil, :include_blank => true)
Examples:
a default ActiveSupport::TimeZone if the object's time zone is +nil+.
Finally, this method supports a :default option, which selects
of your choice)
for obtaining a list of the US time zones, or a Regexp to select the zones
(long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
as +priority_zones+, so that they will be listed above the rest of the
You can also supply an array of ActiveSupport::TimeZone objects
for more information.)
different time zone model object. (See +time_zone_options_for_select+
to ActiveSupport::TimeZone. This may be used by users to specify a
this method also supports a :model option, which defaults
In addition to the :include_blank option documented above,
#time_zone_options_for_select to generate the list of option tags.
Return select and option tags for the given object and method, using
def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {}) InstanceTag.new(object, method, self, options.delete(:object)).to_time_zone_select_tag(priority_zones, options, html_options) end