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]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@759 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
David Heinemeier Hansson 2005-02-23 12:54:58 +00:00
parent 69f18a7a81
commit 2bf29b3485
3 changed files with 216 additions and 3 deletions

View File

@ -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]

View File

@ -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,6 +276,16 @@ 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

View File

@ -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