actionpack 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +149 -7
- data/MIT-LICENSE +1 -1
- data/README +1 -1
- data/Rakefile +5 -6
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions/model_assertions.rb +2 -1
- data/lib/action_controller/assertions/response_assertions.rb +4 -2
- data/lib/action_controller/assertions/routing_assertions.rb +3 -3
- data/lib/action_controller/assertions/selector_assertions.rb +30 -27
- data/lib/action_controller/assertions/tag_assertions.rb +3 -3
- data/lib/action_controller/base.rb +103 -129
- data/lib/action_controller/benchmarking.rb +3 -3
- data/lib/action_controller/caching.rb +41 -652
- data/lib/action_controller/caching/actions.rb +144 -0
- data/lib/action_controller/caching/fragments.rb +138 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sql_cache.rb +18 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/cgi_ext/cookie.rb +27 -23
- data/lib/action_controller/cgi_ext/stdinput.rb +1 -0
- data/lib/action_controller/cgi_process.rb +6 -4
- data/lib/action_controller/components.rb +7 -6
- data/lib/action_controller/cookies.rb +31 -19
- data/lib/action_controller/dispatcher.rb +51 -84
- data/lib/action_controller/filters.rb +295 -421
- data/lib/action_controller/flash.rb +1 -6
- data/lib/action_controller/headers.rb +31 -0
- data/lib/action_controller/helpers.rb +26 -9
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +65 -13
- data/lib/action_controller/layout.rb +24 -39
- data/lib/action_controller/mime_responds.rb +7 -3
- data/lib/action_controller/mime_type.rb +25 -9
- data/lib/action_controller/mime_types.rb +1 -1
- data/lib/action_controller/polymorphic_routes.rb +32 -17
- data/lib/action_controller/record_identifier.rb +10 -4
- data/lib/action_controller/request.rb +46 -30
- data/lib/action_controller/request_forgery_protection.rb +10 -9
- data/lib/action_controller/request_profiler.rb +29 -8
- data/lib/action_controller/rescue.rb +24 -24
- data/lib/action_controller/resources.rb +66 -23
- data/lib/action_controller/response.rb +2 -2
- data/lib/action_controller/routing.rb +113 -1229
- data/lib/action_controller/routing/builder.rb +204 -0
- data/lib/action_controller/{routing_optimisation.rb → routing/optimisations.rb} +13 -12
- data/lib/action_controller/routing/recognition_optimisation.rb +158 -0
- data/lib/action_controller/routing/route.rb +240 -0
- data/lib/action_controller/routing/route_set.rb +435 -0
- data/lib/action_controller/routing/routing_ext.rb +46 -0
- data/lib/action_controller/routing/segments.rb +283 -0
- data/lib/action_controller/session/active_record_store.rb +13 -8
- data/lib/action_controller/session/cookie_store.rb +20 -17
- data/lib/action_controller/session_management.rb +10 -3
- data/lib/action_controller/streaming.rb +45 -31
- data/lib/action_controller/test_case.rb +33 -23
- data/lib/action_controller/test_process.rb +39 -35
- data/lib/action_controller/url_rewriter.rb +18 -12
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +11 -3
- data/lib/action_view/base.rb +73 -390
- data/lib/action_view/helpers/active_record_helper.rb +83 -62
- data/lib/action_view/helpers/asset_tag_helper.rb +101 -44
- data/lib/action_view/helpers/atom_feed_helper.rb +35 -7
- data/lib/action_view/helpers/benchmark_helper.rb +5 -3
- data/lib/action_view/helpers/cache_helper.rb +3 -2
- data/lib/action_view/helpers/capture_helper.rb +1 -2
- data/lib/action_view/helpers/date_helper.rb +104 -82
- data/lib/action_view/helpers/form_helper.rb +148 -75
- data/lib/action_view/helpers/form_options_helper.rb +44 -23
- data/lib/action_view/helpers/form_tag_helper.rb +22 -13
- data/lib/action_view/helpers/javascripts/controls.js +1 -1
- data/lib/action_view/helpers/javascripts/dragdrop.js +1 -1
- data/lib/action_view/helpers/javascripts/effects.js +1 -1
- data/lib/action_view/helpers/number_helper.rb +10 -3
- data/lib/action_view/helpers/prototype_helper.rb +61 -29
- data/lib/action_view/helpers/record_tag_helper.rb +3 -3
- data/lib/action_view/helpers/sanitize_helper.rb +23 -17
- data/lib/action_view/helpers/scriptaculous_helper.rb +86 -60
- data/lib/action_view/helpers/text_helper.rb +153 -125
- data/lib/action_view/helpers/url_helper.rb +83 -28
- data/lib/action_view/inline_template.rb +20 -0
- data/lib/action_view/partial_template.rb +70 -0
- data/lib/action_view/partials.rb +31 -73
- data/lib/action_view/template.rb +127 -0
- data/lib/action_view/template_error.rb +8 -7
- data/lib/action_view/template_finder.rb +177 -0
- data/lib/action_view/template_handler.rb +18 -1
- data/lib/action_view/template_handlers/builder.rb +10 -2
- data/lib/action_view/template_handlers/compilable.rb +128 -0
- data/lib/action_view/template_handlers/erb.rb +37 -2
- data/lib/action_view/template_handlers/rjs.rb +14 -1
- data/lib/action_view/test_case.rb +58 -0
- data/test/abstract_unit.rb +1 -1
- data/test/active_record_unit.rb +3 -6
- data/test/activerecord/active_record_store_test.rb +1 -2
- data/test/activerecord/render_partial_with_record_identification_test.rb +158 -41
- data/test/adv_attr_test.rb +20 -0
- data/test/controller/action_pack_assertions_test.rb +16 -19
- data/test/controller/addresses_render_test.rb +1 -1
- data/test/controller/assert_select_test.rb +13 -6
- data/test/controller/base_test.rb +48 -2
- data/test/controller/benchmark_test.rb +1 -2
- data/test/controller/caching_test.rb +282 -21
- data/test/controller/capture_test.rb +1 -1
- data/test/controller/cgi_test.rb +1 -1
- data/test/controller/components_test.rb +1 -1
- data/test/controller/content_type_test.rb +2 -2
- data/test/controller/cookie_test.rb +13 -2
- data/test/controller/custom_handler_test.rb +14 -10
- data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -1
- data/test/controller/dispatcher_test.rb +31 -49
- data/test/controller/fake_controllers.rb +17 -0
- data/test/controller/fake_models.rb +6 -0
- data/test/controller/filter_params_test.rb +14 -8
- data/test/controller/filters_test.rb +44 -16
- data/test/controller/flash_test.rb +2 -2
- data/test/controller/header_test.rb +14 -0
- data/test/controller/helper_test.rb +19 -15
- data/test/controller/html-scanner/document_test.rb +1 -2
- data/test/controller/html-scanner/node_test.rb +1 -2
- data/test/controller/html-scanner/sanitizer_test.rb +8 -5
- data/test/controller/html-scanner/tag_node_test.rb +1 -2
- data/test/controller/html-scanner/text_node_test.rb +2 -3
- data/test/controller/html-scanner/tokenizer_test.rb +8 -2
- data/test/controller/http_authentication_test.rb +1 -1
- data/test/controller/integration_test.rb +14 -16
- data/test/controller/integration_upload_test.rb +43 -0
- data/test/controller/layout_test.rb +26 -6
- data/test/controller/mime_responds_test.rb +39 -7
- data/test/controller/mime_type_test.rb +29 -5
- data/test/controller/new_render_test.rb +105 -34
- data/test/controller/polymorphic_routes_test.rb +32 -20
- data/test/controller/record_identifier_test.rb +38 -2
- data/test/controller/redirect_test.rb +21 -1
- data/test/controller/render_test.rb +59 -15
- data/test/controller/request_forgery_protection_test.rb +92 -5
- data/test/controller/request_test.rb +64 -6
- data/test/controller/rescue_test.rb +22 -6
- data/test/controller/resources_test.rb +102 -14
- data/test/controller/routing_test.rb +231 -19
- data/test/controller/selector_test.rb +2 -2
- data/test/controller/send_file_test.rb +14 -3
- data/test/controller/session/cookie_store_test.rb +16 -4
- data/test/controller/session/mem_cache_store_test.rb +3 -4
- data/test/controller/session_fixation_test.rb +1 -1
- data/test/controller/session_management_test.rb +23 -1
- data/test/controller/test_test.rb +39 -18
- data/test/controller/url_rewriter_test.rb +35 -1
- data/test/controller/verification_test.rb +1 -1
- data/test/controller/view_paths_test.rb +15 -12
- data/test/controller/webservice_test.rb +48 -3
- data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
- data/test/fixtures/company.rb +1 -0
- data/test/fixtures/customers/_customer.html.erb +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +6 -0
- data/test/fixtures/functional_caching/_partial.erb +3 -0
- data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
- data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
- data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
- data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
- data/test/fixtures/mascot.rb +3 -0
- data/test/fixtures/mascots.yml +4 -0
- data/test/fixtures/mascots/_mascot.html.erb +1 -0
- data/test/fixtures/multipart/boundary_problem_file +10 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/public/javascripts/controls.js +1 -0
- data/test/fixtures/public/javascripts/dragdrop.js +1 -0
- data/test/fixtures/public/javascripts/effects.js +1 -0
- data/test/fixtures/public/javascripts/prototype.js +1 -0
- data/test/fixtures/public/javascripts/version.1.0.js +1 -0
- data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
- data/test/fixtures/reply.rb +1 -0
- data/test/fixtures/shared.html.erb +1 -0
- data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
- data/test/fixtures/test/_customer_counter.erb +1 -0
- data/test/fixtures/test/_form.erb +1 -0
- data/test/fixtures/test/_labelling_form.erb +1 -0
- data/test/fixtures/test/_raise.html.erb +1 -0
- data/test/fixtures/test/greeting.js.rjs +1 -0
- data/test/fixtures/topics/_topic.html.erb +1 -0
- data/test/template/active_record_helper_test.rb +25 -8
- data/test/template/asset_tag_helper_test.rb +100 -17
- data/test/template/atom_feed_helper_test.rb +29 -1
- data/test/template/benchmark_helper_test.rb +10 -22
- data/test/template/date_helper_test.rb +455 -153
- data/test/template/erb_util_test.rb +10 -42
- data/test/template/form_helper_test.rb +192 -66
- data/test/template/form_options_helper_test.rb +19 -8
- data/test/template/form_tag_helper_test.rb +11 -8
- data/test/template/javascript_helper_test.rb +3 -9
- data/test/template/number_helper_test.rb +6 -3
- data/test/template/prototype_helper_test.rb +27 -40
- data/test/template/record_tag_helper_test.rb +54 -0
- data/test/template/sanitize_helper_test.rb +5 -6
- data/test/template/scriptaculous_helper_test.rb +7 -13
- data/test/template/tag_helper_test.rb +3 -6
- data/test/template/template_finder_test.rb +73 -0
- data/test/template/template_object_test.rb +95 -0
- data/test/template/test_test.rb +56 -0
- data/test/template/text_helper_test.rb +46 -33
- data/test/template/url_helper_test.rb +8 -10
- metadata +65 -12
- data/lib/action_view/compiled_templates.rb +0 -69
- data/test/action_view_test.rb +0 -44
- data/test/activerecord/fixtures_test.rb +0 -24
- data/test/controller/fragment_store_setting_test.rb +0 -47
- data/test/template/compiled_templates_test.rb +0 -197
- data/test/template/deprecate_ivars_test.rb +0 -51
|
@@ -26,7 +26,7 @@ module ActionView
|
|
|
26
26
|
# end
|
|
27
27
|
#
|
|
28
28
|
# app/views/posts/index.atom.builder:
|
|
29
|
-
# atom_feed
|
|
29
|
+
# atom_feed do |feed|
|
|
30
30
|
# feed.title("My great blog!")
|
|
31
31
|
# feed.updated((@posts.first.created_at))
|
|
32
32
|
#
|
|
@@ -42,25 +42,53 @@ module ActionView
|
|
|
42
42
|
# end
|
|
43
43
|
# end
|
|
44
44
|
#
|
|
45
|
-
# The options
|
|
45
|
+
# The options for atom_feed are:
|
|
46
46
|
#
|
|
47
|
-
# * <tt>:schema_date</tt>: Required. The date at which the tag scheme for the feed was first used. A good default is the year you created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information.
|
|
48
47
|
# * <tt>:language</tt>: Defaults to "en-US".
|
|
49
48
|
# * <tt>:root_url</tt>: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
|
|
50
49
|
# * <tt>:url</tt>: The URL for this feed. Defaults to the current URL.
|
|
50
|
+
# * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
|
|
51
|
+
# created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
|
|
52
|
+
# 2005 is used (as an "I don't care" value).
|
|
53
|
+
#
|
|
54
|
+
# Other namespaces can be added to the root element:
|
|
55
|
+
#
|
|
56
|
+
# app/views/posts/index.atom.builder:
|
|
57
|
+
# atom_feed({'xmlns:app' => 'http://www.w3.org/2007/app',
|
|
58
|
+
# 'xmlns:openSearch' => 'http://a9.com/-/spec/opensearch/1.1/'}) do |feed|
|
|
59
|
+
# feed.title("My great blog!")
|
|
60
|
+
# feed.updated((@posts.first.created_at))
|
|
61
|
+
# feed.tag!(openSearch:totalResults, 10)
|
|
62
|
+
#
|
|
63
|
+
# for post in @posts
|
|
64
|
+
# feed.entry(post) do |entry|
|
|
65
|
+
# entry.title(post.title)
|
|
66
|
+
# entry.content(post.body, :type => 'html')
|
|
67
|
+
# entry.tag!('app:edited', Time.now)
|
|
68
|
+
#
|
|
69
|
+
# entry.author do |author|
|
|
70
|
+
# author.name("DHH")
|
|
71
|
+
# end
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
51
76
|
#
|
|
52
77
|
# atom_feed yields an AtomFeedBuilder instance.
|
|
53
78
|
def atom_feed(options = {}, &block)
|
|
54
|
-
if options[:schema_date]
|
|
55
|
-
logger.warn("You must provide the :schema_date option to atom_feed for your feed to be valid. A good default is the year you first created this feed.") unless logger.nil?
|
|
56
|
-
else
|
|
79
|
+
if options[:schema_date]
|
|
57
80
|
options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
|
|
81
|
+
else
|
|
82
|
+
options[:schema_date] = "2005" # The Atom spec copyright date
|
|
58
83
|
end
|
|
59
84
|
|
|
60
85
|
xml = options[:xml] || eval("xml", block.binding)
|
|
61
86
|
xml.instruct!
|
|
62
87
|
|
|
63
|
-
|
|
88
|
+
feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
|
|
89
|
+
feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}
|
|
90
|
+
|
|
91
|
+
xml.feed(feed_opts) do
|
|
64
92
|
xml.id("tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}")
|
|
65
93
|
xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port))
|
|
66
94
|
xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url)
|
|
@@ -21,11 +21,13 @@ module ActionView
|
|
|
21
21
|
# You may give an optional logger level as the second argument
|
|
22
22
|
# (:debug, :info, :warn, :error); the default value is :info.
|
|
23
23
|
def benchmark(message = "Benchmarking", level = :info)
|
|
24
|
-
if
|
|
24
|
+
if controller.logger
|
|
25
25
|
real = Benchmark.realtime { yield }
|
|
26
|
-
|
|
26
|
+
controller.logger.send(level, "#{message} (#{'%.5f' % real})")
|
|
27
|
+
else
|
|
28
|
+
yield
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
|
-
end
|
|
33
|
+
end
|
|
@@ -31,8 +31,9 @@ module ActionView
|
|
|
31
31
|
# <%= render :partial => "topics", :collection => @topic_list %>
|
|
32
32
|
# <i>Topics listed alphabetically</i>
|
|
33
33
|
# <% end %>
|
|
34
|
-
def cache(name = {}, &block)
|
|
35
|
-
|
|
34
|
+
def cache(name = {}, options = nil, &block)
|
|
35
|
+
handler = Template.handler_class_for_extension(current_render_extension.to_sym)
|
|
36
|
+
handler.new(@controller).cache_fragment(block, name, options)
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
end
|
|
@@ -118,8 +118,7 @@ module ActionView
|
|
|
118
118
|
# for elements that will be fragment cached.
|
|
119
119
|
#
|
|
120
120
|
# The deprecated way of accessing a content_for block is to use an instance variable
|
|
121
|
-
# named <tt>@content_for_#{name_of_the_content_block}</tt>.
|
|
122
|
-
# would be available as <tt><%= @content_for_footer %></tt>. The preferred usage is now
|
|
121
|
+
# named <tt>@content_for_#{name_of_the_content_block}</tt>. The preferred usage is now
|
|
123
122
|
# <tt><%= yield :footer %></tt>.
|
|
124
123
|
def content_for(name, content = nil, &block)
|
|
125
124
|
existing_content_for = instance_variable_get("@content_for_#{name}").to_s
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "date"
|
|
2
|
+
require 'action_view/helpers/tag_helper'
|
|
2
3
|
|
|
3
4
|
module ActionView
|
|
4
5
|
module Helpers
|
|
@@ -11,31 +12,32 @@ module ActionView
|
|
|
11
12
|
# * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true, the select_month
|
|
12
13
|
# method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead of "date[month]".
|
|
13
14
|
module DateHelper
|
|
15
|
+
include ActionView::Helpers::TagHelper
|
|
14
16
|
DEFAULT_PREFIX = 'date' unless const_defined?('DEFAULT_PREFIX')
|
|
15
17
|
|
|
16
18
|
# Reports the approximate distance in time between two Time or Date objects or integers as seconds.
|
|
17
19
|
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs
|
|
18
|
-
# Distances are reported
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# With include_seconds = true and the difference < 1 minute 29 seconds
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
20
|
+
# Distances are reported based on the following table:
|
|
21
|
+
#
|
|
22
|
+
# 0 <-> 29 secs # => less than a minute
|
|
23
|
+
# 30 secs <-> 1 min, 29 secs # => 1 minute
|
|
24
|
+
# 1 min, 30 secs <-> 44 mins, 29 secs # => [2..44] minutes
|
|
25
|
+
# 44 mins, 30 secs <-> 89 mins, 29 secs # => about 1 hour
|
|
26
|
+
# 89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours
|
|
27
|
+
# 23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs # => 1 day
|
|
28
|
+
# 47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days
|
|
29
|
+
# 29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 1 month
|
|
30
|
+
# 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months
|
|
31
|
+
# 1 yr <-> 2 yrs minus 1 secs # => about 1 year
|
|
32
|
+
# 2 yrs <-> max time or date # => over [2..X] years
|
|
33
|
+
#
|
|
34
|
+
# With <tt>include_seconds</tt> = true and the difference < 1 minute 29 seconds:
|
|
35
|
+
# 0-4 secs # => less than 5 seconds
|
|
36
|
+
# 5-9 secs # => less than 10 seconds
|
|
37
|
+
# 10-19 secs # => less than 20 seconds
|
|
38
|
+
# 20-39 secs # => half a minute
|
|
39
|
+
# 40-59 secs # => less than a minute
|
|
40
|
+
# 60-89 secs # => 1 minute
|
|
39
41
|
#
|
|
40
42
|
# ==== Examples
|
|
41
43
|
# from_time = Time.now
|
|
@@ -102,15 +104,17 @@ module ActionView
|
|
|
102
104
|
|
|
103
105
|
# Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by
|
|
104
106
|
# +method+) on an object assigned to the template (identified by +object+). It's possible to tailor the selects through the +options+ hash,
|
|
105
|
-
# which accepts all the keys that each of the individual select builders do (like
|
|
107
|
+
# which accepts all the keys that each of the individual select builders do (like <tt>:use_month_numbers</tt> for select_month) as well as a range of
|
|
106
108
|
# discard options. The discard options are <tt>:discard_year</tt>, <tt>:discard_month</tt> and <tt>:discard_day</tt>. Set to true, they'll
|
|
107
109
|
# drop the respective select. Discarding the month select will also automatically discard the day select. It's also possible to explicitly
|
|
108
110
|
# set the order of the tags using the <tt>:order</tt> option with an array of symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in
|
|
109
111
|
# the desired order. Symbols may be omitted and the respective select is not included.
|
|
110
112
|
#
|
|
111
|
-
# Pass the <tt>:default</tt> option to set the default date. Use a Time object or a Hash of
|
|
113
|
+
# Pass the <tt>:default</tt> option to set the default date. Use a Time object or a Hash of <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:minute</tt>, and <tt>:second</tt>.
|
|
112
114
|
#
|
|
113
|
-
# Passing
|
|
115
|
+
# Passing <tt>:disabled => true</tt> as part of the +options+ will make elements inaccessible for change.
|
|
116
|
+
#
|
|
117
|
+
# If anything is passed in the +html_options+ hash it will be applied to every select tag in the set.
|
|
114
118
|
#
|
|
115
119
|
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
|
|
116
120
|
#
|
|
@@ -148,14 +152,16 @@ module ActionView
|
|
|
148
152
|
#
|
|
149
153
|
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month
|
|
150
154
|
# choices are valid.
|
|
151
|
-
def date_select(object_name, method, options = {})
|
|
152
|
-
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_date_select_tag(options)
|
|
155
|
+
def date_select(object_name, method, options = {}, html_options = {})
|
|
156
|
+
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_date_select_tag(options, html_options)
|
|
153
157
|
end
|
|
154
158
|
|
|
155
159
|
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a specified
|
|
156
160
|
# time-based attribute (identified by +method+) on an object assigned to the template (identified by +object+).
|
|
157
161
|
# You can include the seconds with <tt>:include_seconds</tt>.
|
|
158
162
|
#
|
|
163
|
+
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
|
164
|
+
#
|
|
159
165
|
# ==== Examples
|
|
160
166
|
# # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute
|
|
161
167
|
# time_select("post", "sunrise")
|
|
@@ -181,13 +187,15 @@ module ActionView
|
|
|
181
187
|
#
|
|
182
188
|
# Note: If the day is not included as an option but the month is, the day will be set to the 1st to ensure that all month
|
|
183
189
|
# choices are valid.
|
|
184
|
-
def time_select(object_name, method, options = {})
|
|
185
|
-
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_time_select_tag(options)
|
|
190
|
+
def time_select(object_name, method, options = {}, html_options = {})
|
|
191
|
+
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_time_select_tag(options, html_options)
|
|
186
192
|
end
|
|
187
193
|
|
|
188
194
|
# Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based
|
|
189
195
|
# attribute (identified by +method+) on an object assigned to the template (identified by +object+). Examples:
|
|
190
196
|
#
|
|
197
|
+
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
|
198
|
+
#
|
|
191
199
|
# ==== Examples
|
|
192
200
|
# # Generates a datetime select that, when POSTed, will be stored in the post variable in the written_on attribute
|
|
193
201
|
# datetime_select("post", "written_on")
|
|
@@ -205,8 +213,8 @@ module ActionView
|
|
|
205
213
|
# datetime_select("post", "written_on", :discard_type => true)
|
|
206
214
|
#
|
|
207
215
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
|
208
|
-
def datetime_select(object_name, method, options = {})
|
|
209
|
-
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_datetime_select_tag(options)
|
|
216
|
+
def datetime_select(object_name, method, options = {}, html_options = {})
|
|
217
|
+
InstanceTag.new(object_name, method, self, nil, options.delete(:object)).to_datetime_select_tag(options, html_options)
|
|
210
218
|
end
|
|
211
219
|
|
|
212
220
|
# Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the +datetime+.
|
|
@@ -215,6 +223,8 @@ module ActionView
|
|
|
215
223
|
# will be appended onto the <tt>:order</tt> passed in. You can also add <tt>:date_separator</tt> and <tt>:time_separator</tt>
|
|
216
224
|
# keys to the +options+ to control visual display of the elements.
|
|
217
225
|
#
|
|
226
|
+
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
|
227
|
+
#
|
|
218
228
|
# ==== Examples
|
|
219
229
|
# my_date_time = Time.now + 4.days
|
|
220
230
|
#
|
|
@@ -240,9 +250,9 @@ module ActionView
|
|
|
240
250
|
# # prefixed with 'payday' rather than 'date'
|
|
241
251
|
# select_datetime(my_date_time, :prefix => 'payday')
|
|
242
252
|
#
|
|
243
|
-
def select_datetime(datetime = Time.
|
|
253
|
+
def select_datetime(datetime = Time.current, options = {}, html_options = {})
|
|
244
254
|
separator = options[:datetime_separator] || ''
|
|
245
|
-
select_date(datetime, options) + separator + select_time(datetime, options)
|
|
255
|
+
select_date(datetime, options, html_options) + separator + select_time(datetime, options, html_options)
|
|
246
256
|
end
|
|
247
257
|
|
|
248
258
|
# Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+.
|
|
@@ -250,6 +260,8 @@ module ActionView
|
|
|
250
260
|
# symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not supply a Symbol, it
|
|
251
261
|
# will be appended onto the <tt>:order</tt> passed in.
|
|
252
262
|
#
|
|
263
|
+
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
|
264
|
+
#
|
|
253
265
|
# ==== Examples
|
|
254
266
|
# my_date = Time.today + 6.days
|
|
255
267
|
#
|
|
@@ -271,13 +283,13 @@ module ActionView
|
|
|
271
283
|
# # prefixed with 'payday' rather than 'date'
|
|
272
284
|
# select_datetime(my_date_time, :prefix => 'payday')
|
|
273
285
|
#
|
|
274
|
-
def select_date(date = Date.
|
|
286
|
+
def select_date(date = Date.current, options = {}, html_options = {})
|
|
275
287
|
options[:order] ||= []
|
|
276
288
|
[:year, :month, :day].each { |o| options[:order].push(o) unless options[:order].include?(o) }
|
|
277
289
|
|
|
278
290
|
select_date = ''
|
|
279
291
|
options[:order].each do |o|
|
|
280
|
-
select_date << self.send("select_#{o}", date, options)
|
|
292
|
+
select_date << self.send("select_#{o}", date, options, html_options)
|
|
281
293
|
end
|
|
282
294
|
select_date
|
|
283
295
|
end
|
|
@@ -286,6 +298,8 @@ module ActionView
|
|
|
286
298
|
# You can set <tt>:time_separator</tt> key to format the output, and
|
|
287
299
|
# the <tt>:include_seconds</tt> option to include an input for seconds.
|
|
288
300
|
#
|
|
301
|
+
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
|
302
|
+
#
|
|
289
303
|
# ==== Examples
|
|
290
304
|
# my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
|
|
291
305
|
#
|
|
@@ -307,9 +321,9 @@ module ActionView
|
|
|
307
321
|
# # separated by ':' and includes an input for seconds
|
|
308
322
|
# select_time(my_time, :time_separator => ':', :include_seconds => true)
|
|
309
323
|
#
|
|
310
|
-
def select_time(datetime = Time.
|
|
324
|
+
def select_time(datetime = Time.current, options = {}, html_options = {})
|
|
311
325
|
separator = options[:time_separator] || ''
|
|
312
|
-
select_hour(datetime, options) + separator + select_minute(datetime, options) + (options[:include_seconds] ? separator + select_second(datetime, options) : '')
|
|
326
|
+
select_hour(datetime, options, html_options) + separator + select_minute(datetime, options, html_options) + (options[:include_seconds] ? separator + select_second(datetime, options, html_options) : '')
|
|
313
327
|
end
|
|
314
328
|
|
|
315
329
|
# Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
|
|
@@ -329,7 +343,7 @@ module ActionView
|
|
|
329
343
|
# # that is named 'interval' rather than 'second'
|
|
330
344
|
# select_second(my_time, :field_name => 'interval')
|
|
331
345
|
#
|
|
332
|
-
def select_second(datetime, options = {})
|
|
346
|
+
def select_second(datetime, options = {}, html_options = {})
|
|
333
347
|
val = datetime ? (datetime.kind_of?(Fixnum) ? datetime : datetime.sec) : ''
|
|
334
348
|
if options[:use_hidden]
|
|
335
349
|
options[:include_seconds] ? hidden_html(options[:field_name] || 'second', val, options) : ''
|
|
@@ -337,11 +351,12 @@ module ActionView
|
|
|
337
351
|
second_options = []
|
|
338
352
|
0.upto(59) do |second|
|
|
339
353
|
second_options << ((val == second) ?
|
|
340
|
-
|
|
341
|
-
|
|
354
|
+
content_tag(:option, leading_zero_on_single_digits(second), :value => leading_zero_on_single_digits(second), :selected => "selected") :
|
|
355
|
+
content_tag(:option, leading_zero_on_single_digits(second), :value => leading_zero_on_single_digits(second))
|
|
342
356
|
)
|
|
357
|
+
second_options << "\n"
|
|
343
358
|
end
|
|
344
|
-
select_html(options[:field_name] || 'second', second_options.join, options)
|
|
359
|
+
select_html(options[:field_name] || 'second', second_options.join, options, html_options)
|
|
345
360
|
end
|
|
346
361
|
end
|
|
347
362
|
|
|
@@ -363,7 +378,7 @@ module ActionView
|
|
|
363
378
|
# # that is named 'stride' rather than 'second'
|
|
364
379
|
# select_minute(my_time, :field_name => 'stride')
|
|
365
380
|
#
|
|
366
|
-
def select_minute(datetime, options = {})
|
|
381
|
+
def select_minute(datetime, options = {}, html_options = {})
|
|
367
382
|
val = datetime ? (datetime.kind_of?(Fixnum) ? datetime : datetime.min) : ''
|
|
368
383
|
if options[:use_hidden]
|
|
369
384
|
hidden_html(options[:field_name] || 'minute', val, options)
|
|
@@ -371,11 +386,12 @@ module ActionView
|
|
|
371
386
|
minute_options = []
|
|
372
387
|
0.step(59, options[:minute_step] || 1) do |minute|
|
|
373
388
|
minute_options << ((val == minute) ?
|
|
374
|
-
|
|
375
|
-
|
|
389
|
+
content_tag(:option, leading_zero_on_single_digits(minute), :value => leading_zero_on_single_digits(minute), :selected => "selected") :
|
|
390
|
+
content_tag(:option, leading_zero_on_single_digits(minute), :value => leading_zero_on_single_digits(minute))
|
|
376
391
|
)
|
|
392
|
+
minute_options << "\n"
|
|
377
393
|
end
|
|
378
|
-
select_html(options[:field_name] || 'minute', minute_options.join, options)
|
|
394
|
+
select_html(options[:field_name] || 'minute', minute_options.join, options, html_options)
|
|
379
395
|
end
|
|
380
396
|
end
|
|
381
397
|
|
|
@@ -396,7 +412,7 @@ module ActionView
|
|
|
396
412
|
# # that is named 'stride' rather than 'second'
|
|
397
413
|
# select_minute(my_time, :field_name => 'stride')
|
|
398
414
|
#
|
|
399
|
-
def select_hour(datetime, options = {})
|
|
415
|
+
def select_hour(datetime, options = {}, html_options = {})
|
|
400
416
|
val = datetime ? (datetime.kind_of?(Fixnum) ? datetime : datetime.hour) : ''
|
|
401
417
|
if options[:use_hidden]
|
|
402
418
|
hidden_html(options[:field_name] || 'hour', val, options)
|
|
@@ -404,11 +420,12 @@ module ActionView
|
|
|
404
420
|
hour_options = []
|
|
405
421
|
0.upto(23) do |hour|
|
|
406
422
|
hour_options << ((val == hour) ?
|
|
407
|
-
|
|
408
|
-
|
|
423
|
+
content_tag(:option, leading_zero_on_single_digits(hour), :value => leading_zero_on_single_digits(hour), :selected => "selected") :
|
|
424
|
+
content_tag(:option, leading_zero_on_single_digits(hour), :value => leading_zero_on_single_digits(hour))
|
|
409
425
|
)
|
|
426
|
+
hour_options << "\n"
|
|
410
427
|
end
|
|
411
|
-
select_html(options[:field_name] || 'hour', hour_options.join, options)
|
|
428
|
+
select_html(options[:field_name] || 'hour', hour_options.join, options, html_options)
|
|
412
429
|
end
|
|
413
430
|
end
|
|
414
431
|
|
|
@@ -429,7 +446,7 @@ module ActionView
|
|
|
429
446
|
# # that is named 'due' rather than 'day'
|
|
430
447
|
# select_day(my_time, :field_name => 'due')
|
|
431
448
|
#
|
|
432
|
-
def select_day(date, options = {})
|
|
449
|
+
def select_day(date, options = {}, html_options = {})
|
|
433
450
|
val = date ? (date.kind_of?(Fixnum) ? date : date.day) : ''
|
|
434
451
|
if options[:use_hidden]
|
|
435
452
|
hidden_html(options[:field_name] || 'day', val, options)
|
|
@@ -437,11 +454,12 @@ module ActionView
|
|
|
437
454
|
day_options = []
|
|
438
455
|
1.upto(31) do |day|
|
|
439
456
|
day_options << ((val == day) ?
|
|
440
|
-
|
|
441
|
-
|
|
457
|
+
content_tag(:option, day, :value => day, :selected => "selected") :
|
|
458
|
+
content_tag(:option, day, :value => day)
|
|
442
459
|
)
|
|
460
|
+
day_options << "\n"
|
|
443
461
|
end
|
|
444
|
-
select_html(options[:field_name] || 'day', day_options.join, options)
|
|
462
|
+
select_html(options[:field_name] || 'day', day_options.join, options, html_options)
|
|
445
463
|
end
|
|
446
464
|
end
|
|
447
465
|
|
|
@@ -479,7 +497,7 @@ module ActionView
|
|
|
479
497
|
# # will use keys like "Januar", "Marts."
|
|
480
498
|
# select_month(Date.today, :use_month_names => %w(Januar Februar Marts ...))
|
|
481
499
|
#
|
|
482
|
-
def select_month(date, options = {})
|
|
500
|
+
def select_month(date, options = {}, html_options = {})
|
|
483
501
|
val = date ? (date.kind_of?(Fixnum) ? date : date.month) : ''
|
|
484
502
|
if options[:use_hidden]
|
|
485
503
|
hidden_html(options[:field_name] || 'month', val, options)
|
|
@@ -497,11 +515,12 @@ module ActionView
|
|
|
497
515
|
end
|
|
498
516
|
|
|
499
517
|
month_options << ((val == month_number) ?
|
|
500
|
-
|
|
501
|
-
|
|
518
|
+
content_tag(:option, month_name, :value => month_number, :selected => "selected") :
|
|
519
|
+
content_tag(:option, month_name, :value => month_number)
|
|
502
520
|
)
|
|
521
|
+
month_options << "\n"
|
|
503
522
|
end
|
|
504
|
-
select_html(options[:field_name] || 'month', month_options.join, options)
|
|
523
|
+
select_html(options[:field_name] || 'month', month_options.join, options, html_options)
|
|
505
524
|
end
|
|
506
525
|
end
|
|
507
526
|
|
|
@@ -527,7 +546,7 @@ module ActionView
|
|
|
527
546
|
# # has ascending year values
|
|
528
547
|
# select_year(2006, :start_year => 2000, :end_year => 2010)
|
|
529
548
|
#
|
|
530
|
-
def select_year(date, options = {})
|
|
549
|
+
def select_year(date, options = {}, html_options = {})
|
|
531
550
|
val = date ? (date.kind_of?(Fixnum) ? date : date.year) : ''
|
|
532
551
|
if options[:use_hidden]
|
|
533
552
|
hidden_html(options[:field_name] || 'year', val, options)
|
|
@@ -539,29 +558,31 @@ module ActionView
|
|
|
539
558
|
step_val = start_year < end_year ? 1 : -1
|
|
540
559
|
start_year.step(end_year, step_val) do |year|
|
|
541
560
|
year_options << ((val == year) ?
|
|
542
|
-
|
|
543
|
-
|
|
561
|
+
content_tag(:option, year, :value => year, :selected => "selected") :
|
|
562
|
+
content_tag(:option, year, :value => year)
|
|
544
563
|
)
|
|
564
|
+
year_options << "\n"
|
|
545
565
|
end
|
|
546
|
-
select_html(options[:field_name] || 'year', year_options.join, options)
|
|
566
|
+
select_html(options[:field_name] || 'year', year_options.join, options, html_options)
|
|
547
567
|
end
|
|
548
568
|
end
|
|
549
569
|
|
|
550
570
|
private
|
|
551
571
|
|
|
552
|
-
def select_html(type, html_options, options)
|
|
572
|
+
def select_html(type, html_options, options, select_tag_options = {})
|
|
553
573
|
name_and_id_from_options(options, type)
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
select_html
|
|
574
|
+
select_options = {:id => options[:id], :name => options[:name]}
|
|
575
|
+
select_options.merge!(:disabled => 'disabled') if options[:disabled]
|
|
576
|
+
select_options.merge!(select_tag_options) unless select_tag_options.empty?
|
|
577
|
+
select_html = "\n"
|
|
578
|
+
select_html << content_tag(:option, '', :value => '') + "\n" if options[:include_blank]
|
|
558
579
|
select_html << html_options.to_s
|
|
559
|
-
select_html
|
|
580
|
+
content_tag(:select, select_html, select_options) + "\n"
|
|
560
581
|
end
|
|
561
582
|
|
|
562
583
|
def hidden_html(type, value, options)
|
|
563
584
|
name_and_id_from_options(options, type)
|
|
564
|
-
hidden_html =
|
|
585
|
+
hidden_html = tag(:input, :type => "hidden", :id => options[:id], :name => options[:name], :value => value) + "\n"
|
|
565
586
|
end
|
|
566
587
|
|
|
567
588
|
def name_and_id_from_options(options, type)
|
|
@@ -577,20 +598,20 @@ module ActionView
|
|
|
577
598
|
class InstanceTag #:nodoc:
|
|
578
599
|
include DateHelper
|
|
579
600
|
|
|
580
|
-
def to_date_select_tag(options = {})
|
|
581
|
-
date_or_time_select(options.merge(:discard_hour => true))
|
|
601
|
+
def to_date_select_tag(options = {}, html_options = {})
|
|
602
|
+
date_or_time_select(options.merge(:discard_hour => true), html_options)
|
|
582
603
|
end
|
|
583
604
|
|
|
584
|
-
def to_time_select_tag(options = {})
|
|
585
|
-
date_or_time_select
|
|
605
|
+
def to_time_select_tag(options = {}, html_options = {})
|
|
606
|
+
date_or_time_select(options.merge(:discard_year => true, :discard_month => true), html_options)
|
|
586
607
|
end
|
|
587
608
|
|
|
588
|
-
def to_datetime_select_tag(options = {})
|
|
589
|
-
date_or_time_select
|
|
609
|
+
def to_datetime_select_tag(options = {}, html_options = {})
|
|
610
|
+
date_or_time_select(options, html_options)
|
|
590
611
|
end
|
|
591
612
|
|
|
592
613
|
private
|
|
593
|
-
def date_or_time_select(options)
|
|
614
|
+
def date_or_time_select(options, html_options = {})
|
|
594
615
|
defaults = { :discard_type => true }
|
|
595
616
|
options = defaults.merge(options)
|
|
596
617
|
datetime = value(object)
|
|
@@ -627,7 +648,7 @@ module ActionView
|
|
|
627
648
|
# This ensures AR can reconstruct valid dates using ParseDate
|
|
628
649
|
next if discard[param] && date_or_time_select.empty?
|
|
629
650
|
|
|
630
|
-
date_or_time_select.insert(0, self.send("select_#{param}", datetime, options_with_prefix(position[param], options.merge(:use_hidden => discard[param]))))
|
|
651
|
+
date_or_time_select.insert(0, self.send("select_#{param}", datetime, options_with_prefix(position[param], options.merge(:use_hidden => discard[param])), html_options))
|
|
631
652
|
date_or_time_select.insert(0,
|
|
632
653
|
case param
|
|
633
654
|
when :hour then (discard[:year] && discard[:day] ? "" : " — ")
|
|
@@ -654,7 +675,7 @@ module ActionView
|
|
|
654
675
|
def default_time_from_options(default)
|
|
655
676
|
case default
|
|
656
677
|
when nil
|
|
657
|
-
Time.
|
|
678
|
+
Time.current
|
|
658
679
|
when Date, Time
|
|
659
680
|
default
|
|
660
681
|
else
|
|
@@ -662,26 +683,27 @@ module ActionView
|
|
|
662
683
|
default[:min] ||= default[:minute]
|
|
663
684
|
default[:sec] ||= default[:second]
|
|
664
685
|
|
|
686
|
+
time = Time.current
|
|
687
|
+
|
|
665
688
|
[:year, :month, :day, :hour, :min, :sec].each do |key|
|
|
666
|
-
default[key] ||=
|
|
689
|
+
default[key] ||= time.send(key)
|
|
667
690
|
end
|
|
668
691
|
|
|
669
|
-
Time.
|
|
670
|
-
default[:hour], default[:min], default[:sec])
|
|
692
|
+
Time.utc_time(default[:year], default[:month], default[:day], default[:hour], default[:min], default[:sec])
|
|
671
693
|
end
|
|
672
694
|
end
|
|
673
695
|
end
|
|
674
696
|
|
|
675
697
|
class FormBuilder
|
|
676
|
-
def date_select(method, options = {})
|
|
698
|
+
def date_select(method, options = {}, html_options = {})
|
|
677
699
|
@template.date_select(@object_name, method, options.merge(:object => @object))
|
|
678
700
|
end
|
|
679
701
|
|
|
680
|
-
def time_select(method, options = {})
|
|
702
|
+
def time_select(method, options = {}, html_options = {})
|
|
681
703
|
@template.time_select(@object_name, method, options.merge(:object => @object))
|
|
682
704
|
end
|
|
683
705
|
|
|
684
|
-
def datetime_select(method, options = {})
|
|
706
|
+
def datetime_select(method, options = {}, html_options = {})
|
|
685
707
|
@template.datetime_select(@object_name, method, options.merge(:object => @object))
|
|
686
708
|
end
|
|
687
709
|
end
|