aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/CHANGELOG4
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb57
-rw-r--r--actionpack/test/template/form_options_helper_test.rb158
3 files changed, 216 insertions, 3 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 0a53072233..95d51eceb2 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Added FormOptionsHelper#time_zone_select and FormOptionsHelper#time_zone_options_for_select to work with the new value object TimeZone in Active Record #688 [Jamis Buck]
+
* Added FormHelper#file_field and FormTagHelper#file_field_tag for creating file upload fields
* Added :order option for date_select that allows control over the order in which the date dropdowns is used and which of them should be used #619 [Tim Bates]. Examples:
@@ -25,7 +27,7 @@
* Fixed that on validation errors, scaffold couldn't find template #654 [mindel]
-* Added Base#hide_actions(*names) to hide public methods from a controller that would otherwise have been callable through the URL. For the majority of cases, its preferred just to make the methods you don't want to expose protected or private (so they'll automatically be hidden) -- but if you must have a public method, this is a way to make it uncallable. Base#hidden_actions retrieve the list of all hidden actions for the controller #644 [Nicholas Seckar]
+* Added Base#hide_action(*names) to hide public methods from a controller that would otherwise have been callable through the URL. For the majority of cases, its preferred just to make the methods you don't want to expose protected or private (so they'll automatically be hidden) -- but if you must have a public method, this is a way to make it uncallable. Base#hidden_actions retrieve the list of all hidden actions for the controller #644 [Nicholas Seckar]
* Fixed that a bunch of methods from ActionController::Base was accessible as actions (callable through a URL) when they shouldn't have been #644 [Nicholas Seckar]
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index a2ed1cc113..8ead838d36 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -6,7 +6,9 @@ module ActionView
module Helpers
# Provides a number of methods for turning different kinds of containers into a set of option tags.
# == Options
- # The <tt>collection_select</tt>, <tt>country_select</tt>, and <tt>select</tt> methods take an <tt>options</tt> parameter, a hash.
+ # The <tt>collection_select</tt>, <tt>country_select</tt>, <tt>select</tt>,
+ # and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter,
+ # a hash.
#
# * <tt>:include_blank</tt> - set to true if the first option element of the select element is a blank. Useful if there is not a default value required for the select element.
# select("post", "category", Post::CATEGORIES, {:include_blank => true})
@@ -43,6 +45,18 @@ module ActionView
InstanceTag.new(object, method, self).to_country_select_tag(priority_countries, options, html_options)
end
+ # Return select and option tags for the given object and method, using
+ # #time_zone_options_for_select to generate the list of option tags.
+ #
+ # In addition to the <tt>:include_blank</tt> option documented above,
+ # this method also supports a <tt>:model</tt> option, which defaults
+ # to TimeZone. This may be used by users to specify a different time
+ # zone model object. (See #time_zone_options_for_select for more
+ # information.)
+ def time_zone_select(object, method, priority_zones = nil, options = {}, html_options = {})
+ InstanceTag.new(object, method, self).to_time_zone_select_tag(priority_zones, 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
@@ -164,6 +178,35 @@ module ActionView
return country_options
end
+ # Returns a string of option tags for pretty much any time zone in the
+ # world. Supply a TimeZone object as +selected+ to have it marked as the
+ # selected option tag. You can also supply an array of TimeZone objects
+ # as +priority_zones+, so that they will be listed above the rest of the
+ # (long) list. (You can use TimeZone.us_zones as a convenience for
+ # obtaining a list of the US time zones.)
+ #
+ # By default, +model+ is the TimeZone constant (which can be obtained
+ # in ActiveRecord as a value object). The only requirement is that the
+ # +model+ parameter be an object that responds to #all, and returns
+ # an array of objects that represent time zones.
+ #
+ # NOTE: Only the option tags are returned, you have to wrap this call in
+ # a regular HTML select tag.
+ def time_zone_options_for_select(selected = nil, priority_zones = nil, model = TimeZone)
+ zone_options = ""
+
+ if priority_zones
+ zone_options += options_for_select(priority_zones, selected)
+ zone_options += "<option>-------------</option>\n"
+
+ zones = model.all.reject { |z| priority_zones.include?( z ) }
+ zone_options += options_for_select(zones, selected)
+ else
+ zone_options += options_for_select(model.all, selected)
+ end
+
+ zone_options
+ end
private
# All the countries included in the country_options output.
@@ -233,10 +276,20 @@ module ActionView
content_tag("select", add_blank_option(country_options_for_select(value, priority_countries), options[:include_blank]), html_options)
end
+ def to_time_zone_select_tag(priority_zones, options, html_options)
+ add_default_name_and_id(html_options)
+ content_tag("select",
+ add_blank_option(
+ time_zone_options_for_select(value, priority_zones, options[:model] || TimeZone),
+ options[:include_blank]
+ ), html_options
+ )
+ end
+
private
def add_blank_option(option_tags, add_blank)
add_blank ? "<option></option>\n" + option_tags : option_tags
end
end
end
-end
+end \ No newline at end of file
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 8894e46865..606a5fe35b 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -1,6 +1,26 @@
require 'test/unit'
require File.dirname(__FILE__) + '/../../lib/action_view/helpers/form_options_helper'
+class TimeZone
+ attr_reader :name
+
+ def initialize( name )
+ @name = name
+ end
+
+ def self.all
+ [ "A", "B", "C", "D", "E" ].map { |s| new s }
+ end
+
+ def ==( z )
+ z && @name == z.name
+ end
+
+ def to_s
+ @name
+ end
+end
+
class FormOptionsHelperTest < Test::Unit::TestCase
include ActionView::Helpers::FormOptionsHelper
@@ -8,6 +28,7 @@ class FormOptionsHelperTest < Test::Unit::TestCase
Post = Struct.new('Post', :title, :author_name, :body, :secret, :written_on, :category, :origin)
Continent = Struct.new('Continent', :continent_name, :countries)
Country = Struct.new('Country', :country_id, :country_name)
+ Firm = Struct.new('Firm', :time_zone)
$VERBOSE = old_verbose
def test_collection_options
@@ -104,6 +125,72 @@ class FormOptionsHelperTest < Test::Unit::TestCase
)
end
+ def test_time_zone_options_no_parms
+ opts = time_zone_options_for_select
+ assert_equal "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option>D</option>\n" +
+ "<option>E</option>",
+ opts
+ end
+
+ def test_time_zone_options_with_selected
+ opts = time_zone_options_for_select( TimeZone.new( "D" ) )
+ assert_equal "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option selected=\"selected\">D</option>\n" +
+ "<option>E</option>",
+ opts
+ end
+
+ def test_time_zone_options_with_unknown_selected
+ opts = time_zone_options_for_select( TimeZone.new( "K" ) )
+ assert_equal "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option>D</option>\n" +
+ "<option>E</option>",
+ opts
+ end
+
+ def test_time_zone_options_with_priority_zones
+ zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ opts = time_zone_options_for_select( nil, zones )
+ assert_equal "<option>B</option>\n" +
+ "<option>E</option>" +
+ "<option>-------------</option>\n" +
+ "<option>A</option>\n" +
+ "<option>C</option>\n" +
+ "<option>D</option>",
+ opts
+ end
+
+ def test_time_zone_options_with_selected_priority_zones
+ zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ opts = time_zone_options_for_select( TimeZone.new("E"), zones )
+ assert_equal "<option>B</option>\n" +
+ "<option selected=\"selected\">E</option>" +
+ "<option>-------------</option>\n" +
+ "<option>A</option>\n" +
+ "<option>C</option>\n" +
+ "<option>D</option>",
+ opts
+ end
+
+ def test_time_zone_options_with_unselected_priority_zones
+ zones = [ TimeZone.new( "B" ), TimeZone.new( "E" ) ]
+ opts = time_zone_options_for_select( TimeZone.new("C"), zones )
+ assert_equal "<option>B</option>\n" +
+ "<option>E</option>" +
+ "<option>-------------</option>\n" +
+ "<option>A</option>\n" +
+ "<option selected=\"selected\">C</option>\n" +
+ "<option>D</option>",
+ opts
+ end
+
def test_select
@post = Post.new
@post.category = "<mus>"
@@ -162,4 +249,75 @@ class FormOptionsHelperTest < Test::Unit::TestCase
country_select("post", "origin")
)
end
+
+ def test_time_zone_select
+ @firm = Firm.new( TimeZone.new( "D" ) )
+ html = time_zone_select( "firm", "time_zone" )
+ assert_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" +
+ "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option selected=\"selected\">D</option>\n" +
+ "<option>E</option>" +
+ "</select>",
+ html
+ end
+
+ def test_time_zone_select_with_blank
+ @firm = Firm.new(TimeZone.new("D"))
+ html = time_zone_select("firm", "time_zone", nil, :include_blank => true)
+ assert_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" +
+ "<option></option>\n" +
+ "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option selected=\"selected\">D</option>\n" +
+ "<option>E</option>" +
+ "</select>",
+ html
+ end
+
+ def test_time_zone_select_with_style
+ @firm = Firm.new(TimeZone.new("D"))
+ html = time_zone_select("firm", "time_zone", nil, {},
+ "style" => "color: red")
+ assert_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" +
+ "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option selected=\"selected\">D</option>\n" +
+ "<option>E</option>" +
+ "</select>",
+ html
+ end
+
+ def test_time_zone_select_with_blank_and_style
+ @firm = Firm.new(TimeZone.new("D"))
+ html = time_zone_select("firm", "time_zone", nil,
+ { :include_blank => true }, "style" => "color: red")
+ assert_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\" style=\"color: red\">" +
+ "<option></option>\n" +
+ "<option>A</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option selected=\"selected\">D</option>\n" +
+ "<option>E</option>" +
+ "</select>",
+ html
+ end
+
+ def test_time_zone_select_with_priority_zones
+ @firm = Firm.new(TimeZone.new("D"))
+ zones = [ TimeZone.new("A"), TimeZone.new("D") ]
+ html = time_zone_select("firm", "time_zone", zones )
+ assert_equal "<select id=\"firm_time_zone\" name=\"firm[time_zone]\">" +
+ "<option>A</option>\n" +
+ "<option selected=\"selected\">D</option>" +
+ "<option>-------------</option>\n" +
+ "<option>B</option>\n" +
+ "<option>C</option>\n" +
+ "<option>E</option>" +
+ "</select>",
+ html
+ end
end