module ActionView::Helpers::FormOptionsHelper

def collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})






and tags for the collection of existing return values of
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 = {})











, and tags for the collection of existing return values of
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)

wrap the output in an appropriate tag.
Note: Only the and tags are returned, so you still have to


...





...



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 tag.
* 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 tags.
Parameters:

groups them by tags based on the object relationships of the arguments.
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=\"#{ERB::Util.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}=\"#{ERB::Util.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)

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

\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
  selected, disabled = extract_selected_and_disabled(selected).map do | r |
     Array.wrap(r).map { |item| item.to_s }
  end
  container.map do |element|
    html_attributes = option_html_attributes(element)
    text, value = option_text_and_value(element).map { |item| item.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="#{ERB::Util.html_escape(value)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{ERB::Util.html_escape(text)}</option>)
  end.join("\n").html_safe
end

def options_from_collection_for_select(collection, value_method, text_method, selected = nil)

should produce the desired results.
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
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 = {})


key in the query string, that works for ordinary forms.
form, and parameters extraction gets the last occurrence of any repeated
says key/value pairs have to be sent in the same order they appear in the
the deselected multiple select box), or both fields. Since the HTML specification
This way, the client either sends only the hidden field (representing

every multiple select. The hidden field has the same name as multiple select and blank value.
To prevent this the helper generates an auxiliary hidden field before

wouldn't update roles.

@user.update_attributes(params[:user])

any mass-assignment idiom like
the user deselects all roles from +role_ids+ multiple select box, no +role_ids+ parameter is sent. So,
if an +User+ model has many +roles+ and have +role_ids+ accessor, and in the form that edits roles of the user
web browsers do not send any value to server. Unfortunately this introduces a gotcha:
The HTML specification says when +multiple+ parameter passed to select and all options got deselected

==== Gotcha

tags by specifying the :disabled option. This can either be a single value or an array of values to be disabled.
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