Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
255 lines (232 sloc) 11.114 kb
module ActionView
module Helpers
module FormOptionsHelper
# Generate select and subregion option tags for the given object and method. A
# common use of this would be to allow users to select a state subregion within
# a given country.
#
# object - The model object to generate the select for
# method - The attribute on the object
# parent_region_or_code - An instance of Carmen::Region or a 2-character
# country code.
# options - Other options pertaining to option tag generation. See
# `region_options_for_select`.
# html_options - Options to use when generating the select tag- class,
# id, etc.
#
# Uses region_options_for_select to generate the list of option tags.
#
# Example:
#
# subregion_select(@object, :region, {priority: ['US', 'CA']}, class: 'region')
#
# Returns an `html_safe` string containing the HTML for a select element.
def subregion_select(object, method, parent_region_or_code, options={}, html_options={})
parent_region = determine_parent(parent_region_or_code)
tag = instance_tag(object, method, self, options)
tag.to_region_select_tag(parent_region, options, html_options)
end
# Generate select and country option tags for the given object and method. A
# common use of this would be to allow users to select a state subregion within
# a given country.
#
# object - The model object to generate the select for
# method - The attribute on the object
# options - Other options pertaining to option tag generation. See
# `region_options_for_select`.
# html_options - Options to use when generating the select tag- class,
# id, etc.
#
# Uses region_options_or_select to generate the list of option tags.
#
# Example:
#
# country_select(@object, :region, {priority: ['US', 'CA']}, class: 'region')
#
# Note that in order to preserve compatibility with various existing
# libraries, an alternative API is supported but not recommended:
#
# country_select(@object, :region, ['US', 'CA'], class: region)
#
# Returns an `html_safe` string containing the HTML for a select element.
def country_select(object, method, priorities_or_options = {}, options_or_html_options = {}, html_options = {})
if priorities_or_options.is_a? Array
options = options_or_html_options
options[:priority] = priorities_or_options
else
options = priorities_or_options
html_options = options_or_html_options
end
tag = instance_tag(object, method, self, options)
tag.to_region_select_tag(Carmen::World.instance, options, html_options)
end
# Generate option tags for a collection of regions.
#
# regions - An array or Carmen::RegionCollection containing Carmen::Regions
# selected - the code of the region that should be selected
# options - The hash of options used to customize the output (default: {}):
#
# To use priority regions (which are included in a special section at the
# top of the list), provide an array of region codes at the :priority
# option:
#
# region_options_for_select(@region.subregions, 'US', priority: ['US', 'CA'])
#
# Returns an `html_safe` string containing option tags.
def region_options_for_select(regions, selected=nil, options={})
options.stringify_keys!
priority_region_codes = options['priority'] || []
region_options = ""
unless priority_region_codes.empty?
unless regions.respond_to?(:coded)
regions = Carmen::RegionCollection.new(regions)
end
priority_regions = priority_region_codes.map do |code|
region = regions.coded(code)
[region.name, region.code] if region
end.compact
unless priority_regions.empty?
region_options += options_for_select(priority_regions, selected)
region_options += "<option disabled>-------------</option>"
# If a priority region is selected, don't select it again in the main list.
# This prevents some browsers from selecting the second occurance of this region,
# which makes it difficult to select an alternative priority region.
selected = nil if priority_region_codes.include?(selected)
end
end
main_options = regions.map { |r| [r.name, r.code] }
main_options.sort!{|a, b| a.first.to_s <=> b.first.to_s}
main_options.unshift [options['prompt'], ''] if options['prompt']
region_options += options_for_select(main_options, selected)
region_options.html_safe
end
# Generate select and country option tags with the provided name. A
# common use of this would be to allow users to select a country name
# inside a web form.
#
# name - The name attribute for the select element.
# options - Other options pertaining to option tag generation. See
# `region_options_for_select`.
# html_options - Options to use when generating the select tag- class,
# id, etc.
#
# Uses region_options_or_select to generate the list of option tags.
#
# Example:
#
# country_select_tag('country_code', {priority: ['US', 'CA']}, class: 'region')
#
# Returns an `html_safe` string containing the HTML for a select element.
def country_select_tag(name, value, options={})
subregion_select_tag(name, value, Carmen::World.instance, options)
end
# Generate select and subregion option tags for the given object and method. A
# common use of this would be to allow users to select a state subregion within
# a given country.
#
# name - The name attribute for the select element.
# parent_region_or_code - An instance of Carmen::Region or a 2-character
# country code.
# options - Other options pertaining to option tag generation. See
# `region_options_for_select`.
# html_options - Options to use when generating the select tag- class,
# id, etc.
#
# Uses region_options_or_select to generate the list of option tags.
#
# Example:
#
# subregion_select_tag('state_code', 'US', {priority: ['US', 'CA']}, class: 'region')
#
# Returns an `html_safe` string containing the HTML for a select element.
def subregion_select_tag(name, value, parent_region_or_code, options = {}, html_options = {})
options.stringify_keys!
parent_region = determine_parent(parent_region_or_code)
opts = region_options_for_select(parent_region.subregions, value, options)
html_options = {"name" => name,
"id" => sanitize_to_id(name)}.update(html_options.stringify_keys)
content_tag(:select, opts, html_options)
end
private
def instance_tag(object_name, method_name, template_object, options = {})
if Rails::VERSION::MAJOR == 3
InstanceTag.new(object_name, method_name, template_object, options.delete(:object))
else
ActionView::Helpers::Tags::Base.new(object_name, method_name, template_object, options || {})
end
end
def determine_parent(parent_region_or_code)
case parent_region_or_code
when String
Carmen::Country.coded(parent_region_or_code)
when Array
parent_region_or_code.inject(Carmen::World.instance) { |parent, next_code|
parent.subregions.coded(next_code)
}
else
parent_region_or_code
end
end
end
if Rails::VERSION::MAJOR == 3
class InstanceTag
def to_region_select_tag(parent_region, options = {}, html_options = {})
html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
priority_regions = options[:priority] || []
value = options[:selected] ? options[:selected] : value(object)
opts = add_options(region_options_for_select(parent_region.subregions, value, :priority => priority_regions), options, value)
content_tag("select", opts, html_options)
end
end
end
if Rails::VERSION::MAJOR == 4
module Tags
class Base
def to_region_select_tag(parent_region, options = {}, html_options = {})
html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
value = options[:selected] ? options[:selected] : value(object)
priority_regions = options[:priority] || []
opts = add_options(region_options_for_select(parent_region.subregions, value,
:priority => priority_regions),
options, value)
select = content_tag("select", opts, html_options)
if html_options["multiple"] && options.fetch(:include_hidden, true)
tag("input", :disabled => html_options["disabled"], :name => html_options["name"],
:type => "hidden", :value => "") + select
else
select
end
end
end
end
end
class FormBuilder
# Generate select and country option tags with the provided name. A
# common use of this would be to allow users to select a country name inside a
# web form.
#
# See `FormOptionsHelper::country_select` for more information.
def country_select(method, priorities_or_options = {}, options_or_html_options = {}, html_options = {})
if priorities_or_options.is_a? Array
options = options_or_html_options
options[:priority] = priorities_or_options
else
options = priorities_or_options
html_options = options_or_html_options
end
@template.country_select(@object_name, method, objectify_options(options), @default_options.merge(html_options))
end
# Generate select and subregion option tags with the provided name. A
# common use of this would be to allow users to select a state subregion within
# a given country.
#
# See `FormOptionsHelper::subregion_select` for more information.
def subregion_select(method, parent_region_or_code, options = {}, html_options = {})
@template.subregion_select(@object_name, method, parent_region_or_code, objectify_options(options), @default_options.merge(html_options))
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.