actionpack 3.1.0.beta1 → 3.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +57 -4
- data/README.rdoc +5 -5
- data/lib/abstract_controller/base.rb +25 -13
- data/lib/abstract_controller/callbacks.rb +2 -2
- data/lib/abstract_controller/layouts.rb +3 -3
- data/lib/abstract_controller/rendering.rb +22 -6
- data/lib/abstract_controller/url_for.rb +6 -0
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/compatibility.rb +4 -7
- data/lib/action_controller/metal/implicit_render.rb +7 -9
- data/lib/action_controller/metal/instrumentation.rb +1 -1
- data/lib/action_controller/metal/params_wrapper.rb +37 -26
- data/lib/action_controller/metal/request_forgery_protection.rb +4 -1
- data/lib/action_controller/metal/responder.rb +6 -1
- data/lib/action_controller/metal/url_for.rb +21 -0
- data/lib/action_controller/test_case.rb +6 -1
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
- data/lib/action_dispatch/http/cache.rb +12 -14
- data/lib/action_dispatch/http/rack_cache.rb +6 -2
- data/lib/action_dispatch/http/response.rb +41 -15
- data/lib/action_dispatch/http/url.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +1 -1
- data/lib/action_dispatch/routing.rb +3 -3
- data/lib/action_dispatch/routing/mapper.rb +33 -28
- data/lib/action_dispatch/routing/route_set.rb +6 -3
- data/lib/action_dispatch/routing/url_for.rb +4 -4
- data/lib/action_dispatch/testing/assertions/selector.rb +1 -1
- data/lib/action_dispatch/testing/performance_test.rb +6 -13
- data/lib/action_dispatch/testing/test_process.rb +1 -1
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +1 -0
- data/lib/action_view/base.rb +5 -5
- data/lib/action_view/helpers/asset_paths.rb +0 -1
- data/lib/action_view/helpers/atom_feed_helper.rb +6 -6
- data/lib/action_view/helpers/cache_helper.rb +1 -1
- data/lib/action_view/helpers/capture_helper.rb +6 -2
- data/lib/action_view/helpers/date_helper.rb +119 -75
- data/lib/action_view/helpers/form_helper.rb +26 -36
- data/lib/action_view/helpers/form_options_helper.rb +2 -2
- data/lib/action_view/helpers/form_tag_helper.rb +6 -6
- data/lib/action_view/helpers/translation_helper.rb +4 -4
- data/lib/action_view/helpers/url_helper.rb +1 -1
- data/lib/action_view/lookup_context.rb +5 -5
- data/lib/action_view/path_set.rb +1 -1
- data/lib/action_view/template.rb +5 -5
- data/lib/action_view/template/error.rb +2 -0
- data/lib/action_view/template/handlers/erb.rb +0 -1
- data/lib/action_view/template/resolver.rb +37 -25
- data/lib/sprockets/railtie.rb +3 -3
- metadata +8 -8
@@ -224,6 +224,7 @@ module ActionDispatch
|
|
224
224
|
self.valid_conditions.push(:controller, :action)
|
225
225
|
|
226
226
|
@append = []
|
227
|
+
@prepend = []
|
227
228
|
@disable_clear_and_finalize = false
|
228
229
|
clear!
|
229
230
|
end
|
@@ -232,7 +233,6 @@ module ActionDispatch
|
|
232
233
|
clear! unless @disable_clear_and_finalize
|
233
234
|
eval_block(block)
|
234
235
|
finalize! unless @disable_clear_and_finalize
|
235
|
-
|
236
236
|
nil
|
237
237
|
end
|
238
238
|
|
@@ -240,6 +240,10 @@ module ActionDispatch
|
|
240
240
|
@append << block
|
241
241
|
end
|
242
242
|
|
243
|
+
def prepend(&block)
|
244
|
+
@prepend << block
|
245
|
+
end
|
246
|
+
|
243
247
|
def eval_block(block)
|
244
248
|
if block.arity == 1
|
245
249
|
raise "You are using the old router DSL which has been removed in Rails 3.1. " <<
|
@@ -262,8 +266,6 @@ module ActionDispatch
|
|
262
266
|
end
|
263
267
|
|
264
268
|
def clear!
|
265
|
-
# Clear the controller cache so we may discover new ones
|
266
|
-
@controller_constraints = nil
|
267
269
|
@finalized = false
|
268
270
|
routes.clear
|
269
271
|
named_routes.clear
|
@@ -271,6 +273,7 @@ module ActionDispatch
|
|
271
273
|
:parameters_key => PARAMETERS_KEY,
|
272
274
|
:request_class => request_class
|
273
275
|
)
|
276
|
+
@prepend.each { |blk| eval_block(blk) }
|
274
277
|
end
|
275
278
|
|
276
279
|
def install_helpers(destinations = [ActionController::Base, ActionView::Base], regenerate_code = false)
|
@@ -131,10 +131,10 @@ module ActionDispatch
|
|
131
131
|
#
|
132
132
|
# Examples:
|
133
133
|
#
|
134
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing'
|
135
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
|
136
|
-
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
|
137
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
|
134
|
+
# url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :port => '8080' # => 'http://somehost.org:8080/tasks/testing'
|
135
|
+
# url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
|
136
|
+
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash => true # => 'http://somehost.org/tasks/testing/'
|
137
|
+
# url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
|
138
138
|
def url_for(options = nil)
|
139
139
|
case options
|
140
140
|
when String
|
@@ -169,7 +169,7 @@ module ActionDispatch
|
|
169
169
|
# assert_select "title", "Welcome"
|
170
170
|
#
|
171
171
|
# # Page title is "Welcome" and there is only one title element
|
172
|
-
# assert_select "title", {:count=>1, :text=>"Welcome"},
|
172
|
+
# assert_select "title", {:count => 1, :text => "Welcome"},
|
173
173
|
# "Wrong title or more than one title element"
|
174
174
|
#
|
175
175
|
# # Page contains no forms
|
@@ -1,17 +1,10 @@
|
|
1
1
|
require 'active_support/testing/performance'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# By default, process_time is measured and both flat and graph_html output
|
10
|
-
# formats are written, so you'll have two output files per test method.
|
11
|
-
class PerformanceTest < ActionDispatch::IntegrationTest
|
12
|
-
include ActiveSupport::Testing::Performance
|
13
|
-
end
|
3
|
+
module ActionDispatch
|
4
|
+
# An integration test that runs a code profiler on your test methods.
|
5
|
+
# Profiling output for combinations of each test method, measurement, and
|
6
|
+
# output format are written to your tmp/performance directory.
|
7
|
+
class PerformanceTest < ActionDispatch::IntegrationTest
|
8
|
+
include ActiveSupport::Testing::Performance
|
14
9
|
end
|
15
|
-
rescue NameError
|
16
|
-
$stderr.puts "Specify ruby-prof as application's dependency in Gemfile to run benchmarks."
|
17
10
|
end
|
@@ -29,7 +29,7 @@ module ActionDispatch
|
|
29
29
|
@response.redirect_url
|
30
30
|
end
|
31
31
|
|
32
|
-
# Shortcut for <tt>
|
32
|
+
# Shortcut for <tt>Rack::Test::UploadedFile.new(ActionController::TestCase.fixture_path + path, type)</tt>:
|
33
33
|
#
|
34
34
|
# post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')
|
35
35
|
#
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
data/lib/action_view/base.rb
CHANGED
@@ -85,11 +85,11 @@ module ActionView #:nodoc:
|
|
85
85
|
#
|
86
86
|
# Here are some basic examples:
|
87
87
|
#
|
88
|
-
# xml.em("emphasized")
|
89
|
-
# xml.em { xml.b("emph & bold") }
|
90
|
-
# xml.a("A Link", "href"=>"http://onestepback.org")
|
91
|
-
# xml.target("name"=>"compile", "option"=>"fast")
|
92
|
-
#
|
88
|
+
# xml.em("emphasized") # => <em>emphasized</em>
|
89
|
+
# xml.em { xml.b("emph & bold") } # => <em><b>emph & bold</b></em>
|
90
|
+
# xml.a("A Link", "href" => "http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
|
91
|
+
# xml.target("name" => "compile", "option" => "fast") # => <target option="fast" name="compile"\>
|
92
|
+
# # NOTE: order of attributes is not specified.
|
93
93
|
#
|
94
94
|
# Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
|
95
95
|
#
|
@@ -34,7 +34,7 @@ module ActionView
|
|
34
34
|
# feed.title("My great blog!")
|
35
35
|
# feed.updated(@posts.first.created_at)
|
36
36
|
#
|
37
|
-
#
|
37
|
+
# @posts.each do |post|
|
38
38
|
# feed.entry(post) do |entry|
|
39
39
|
# entry.title(post.title)
|
40
40
|
# entry.content(post.body, :type => 'html')
|
@@ -66,7 +66,7 @@ module ActionView
|
|
66
66
|
# feed.updated((@posts.first.created_at))
|
67
67
|
# feed.tag!(openSearch:totalResults, 10)
|
68
68
|
#
|
69
|
-
#
|
69
|
+
# @posts.each do |post|
|
70
70
|
# feed.entry(post) do |entry|
|
71
71
|
# entry.title(post.title)
|
72
72
|
# entry.content(post.body, :type => 'html')
|
@@ -81,8 +81,8 @@ module ActionView
|
|
81
81
|
#
|
82
82
|
# The Atom spec defines five elements (content rights title subtitle
|
83
83
|
# summary) which may directly contain xhtml content if :type => 'xhtml'
|
84
|
-
# is specified as an attribute.
|
85
|
-
# the enclosing div and xhtml namespace declaration.
|
84
|
+
# is specified as an attribute. If so, this helper will take care of
|
85
|
+
# the enclosing div and xhtml namespace declaration. Example usage:
|
86
86
|
#
|
87
87
|
# entry.summary :type => 'xhtml' do |xhtml|
|
88
88
|
# xhtml.p pluralize(order.line_items.count, "line item")
|
@@ -91,8 +91,8 @@ module ActionView
|
|
91
91
|
# end
|
92
92
|
#
|
93
93
|
#
|
94
|
-
# atom_feed yields an AtomFeedBuilder instance.
|
95
|
-
# an AtomBuilder instance.
|
94
|
+
# <tt>atom_feed</tt> yields an +AtomFeedBuilder+ instance. Nested elements yield
|
95
|
+
# an +AtomBuilder+ instance.
|
96
96
|
def atom_feed(options = {}, &block)
|
97
97
|
if options[:schema_date]
|
98
98
|
options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
|
@@ -3,7 +3,7 @@ module ActionView
|
|
3
3
|
module Helpers
|
4
4
|
module CacheHelper
|
5
5
|
# This helper exposes a method for caching fragments of a view
|
6
|
-
# rather than an entire action or page.
|
6
|
+
# rather than an entire action or page. This technique is useful
|
7
7
|
# caching pieces like menus, lists of newstopics, static HTML
|
8
8
|
# fragments, and so on. This method takes a block that contains
|
9
9
|
# the content you wish to cache.
|
@@ -135,8 +135,12 @@ module ActionView
|
|
135
135
|
# for elements that will be fragment cached.
|
136
136
|
def content_for(name, content = nil, &block)
|
137
137
|
content = capture(&block) if block_given?
|
138
|
-
|
139
|
-
|
138
|
+
if content
|
139
|
+
@view_flow.append(name, content)
|
140
|
+
nil
|
141
|
+
else
|
142
|
+
@view_flow.get(name)
|
143
|
+
end
|
140
144
|
end
|
141
145
|
|
142
146
|
# The same as +content_for+ but when used with streaming flushes
|
@@ -12,14 +12,14 @@ module ActionView
|
|
12
12
|
# select-type methods share a number of common options that are as follows:
|
13
13
|
#
|
14
14
|
# * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
|
15
|
-
# would give birthday[month] instead of date[month] if passed to the select_month method.
|
15
|
+
# would give birthday[month] instead of date[month] if passed to the <tt>select_month</tt> method.
|
16
16
|
# * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
|
17
17
|
# * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true,
|
18
|
-
# the select_month method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
|
19
|
-
# "date[month]".
|
18
|
+
# the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
|
19
|
+
# of "date[month]".
|
20
20
|
module DateHelper
|
21
21
|
# Reports the approximate distance in time between two Time or Date objects or integers as seconds.
|
22
|
-
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs
|
22
|
+
# Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs.
|
23
23
|
# Distances are reported based on the following table:
|
24
24
|
#
|
25
25
|
# 0 <-> 29 secs # => less than a minute
|
@@ -94,9 +94,20 @@ module ActionView
|
|
94
94
|
when 43200..86399 then locale.t :about_x_months, :count => 1
|
95
95
|
when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
|
96
96
|
else
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
fyear = from_time.year
|
98
|
+
fyear += 1 if from_time.month >= 3
|
99
|
+
tyear = to_time.year
|
100
|
+
tyear -= 1 if to_time.month < 3
|
101
|
+
leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
|
102
|
+
minute_offset_for_leap_year = leap_years * 1440
|
103
|
+
# Discount the leap year days when calculating year distance.
|
104
|
+
# e.g. if there are 20 leap year days between 2 dates having the same day
|
105
|
+
# and month then the based on 365 days calculation
|
106
|
+
# the distance in years will come out to over 80 years when in written
|
107
|
+
# english it would read better as about 80 years.
|
108
|
+
minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
|
109
|
+
remainder = (minutes_with_offset % 525600)
|
110
|
+
distance_in_years = (minutes_with_offset / 525600)
|
100
111
|
if remainder < 131400
|
101
112
|
locale.t(:about_x_years, :count => distance_in_years)
|
102
113
|
elsif remainder < 394200
|
@@ -108,7 +119,7 @@ module ActionView
|
|
108
119
|
end
|
109
120
|
end
|
110
121
|
|
111
|
-
# Like distance_of_time_in_words
|
122
|
+
# Like <tt>distance_of_time_in_words</tt>, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
|
112
123
|
#
|
113
124
|
# ==== Examples
|
114
125
|
# time_ago_in_words(3.minutes.from_now) # => 3 minutes
|
@@ -165,7 +176,7 @@ module ActionView
|
|
165
176
|
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
|
166
177
|
#
|
167
178
|
# ==== Examples
|
168
|
-
# # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
|
179
|
+
# # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute.
|
169
180
|
# date_select("post", "written_on")
|
170
181
|
#
|
171
182
|
# # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute,
|
@@ -186,7 +197,7 @@ module ActionView
|
|
186
197
|
# # lacking a year field.
|
187
198
|
# date_select("user", "birthday", :order => [:month, :day])
|
188
199
|
#
|
189
|
-
# # Generates a date select that when POSTed is stored in the
|
200
|
+
# # Generates a date select that when POSTed is stored in the post variable, in the written_on attribute
|
190
201
|
# # which is initially set to the date 3 days from the current date
|
191
202
|
# date_select("post", "written_on", :default => 3.days.from_now)
|
192
203
|
#
|
@@ -194,7 +205,7 @@ module ActionView
|
|
194
205
|
# # that will have a default day of 20.
|
195
206
|
# date_select("credit_card", "bill_due", :default => { :day => 20 })
|
196
207
|
#
|
197
|
-
# # Generates a date select with custom prompts
|
208
|
+
# # Generates a date select with custom prompts.
|
198
209
|
# date_select("post", "written_on", :prompt => { :day => 'Select day', :month => 'Select month', :year => 'Select year' })
|
199
210
|
#
|
200
211
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
@@ -207,29 +218,34 @@ module ActionView
|
|
207
218
|
|
208
219
|
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
|
209
220
|
# specified time-based attribute (identified by +method+) on an object assigned to the template (identified by
|
210
|
-
# +object+). You can include the seconds with <tt>:include_seconds</tt>.
|
221
|
+
# +object+). You can include the seconds with <tt>:include_seconds</tt>. You can get hours in the AM/PM format
|
222
|
+
# with <tt>:ampm</tt> option.
|
211
223
|
#
|
212
224
|
# This method will also generate 3 input hidden tags, for the actual year, month and day unless the option
|
213
|
-
# <tt>:ignore_date</tt> is set to +true+.
|
225
|
+
# <tt>:ignore_date</tt> is set to +true+. If you set the <tt>:ignore_date</tt> to +true+, you must have a
|
226
|
+
# +date_select+ on the same method within the form otherwise an exception will be raised.
|
214
227
|
#
|
215
228
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
216
229
|
#
|
217
230
|
# ==== Examples
|
218
|
-
# # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute
|
231
|
+
# # Creates a time select tag that, when POSTed, will be stored in the post variable in the sunrise attribute.
|
219
232
|
# time_select("post", "sunrise")
|
220
233
|
#
|
221
234
|
# # Creates a time select tag with a seconds field that, when POSTed, will be stored in the post variables in
|
222
235
|
# # the sunrise attribute.
|
223
236
|
# time_select("post", "start_time", :include_seconds => true)
|
224
237
|
#
|
225
|
-
# # You can set the
|
238
|
+
# # You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30 and 45.
|
226
239
|
# time_select 'game', 'game_time', {:minute_step => 15}
|
227
240
|
#
|
228
|
-
# # Creates a time select tag with a custom prompt. Use
|
241
|
+
# # Creates a time select tag with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
229
242
|
# time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
|
230
243
|
# time_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
|
231
244
|
# time_select("post", "written_on", :prompt => true) # generic prompts for all
|
232
245
|
#
|
246
|
+
# # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
|
247
|
+
# time_select 'game', 'game_time', {:ampm => true}
|
248
|
+
#
|
233
249
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
234
250
|
#
|
235
251
|
# 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
|
@@ -246,7 +262,7 @@ module ActionView
|
|
246
262
|
#
|
247
263
|
# ==== Examples
|
248
264
|
# # Generates a datetime select that, when POSTed, will be stored in the post variable in the written_on
|
249
|
-
# # attribute
|
265
|
+
# # attribute.
|
250
266
|
# datetime_select("post", "written_on")
|
251
267
|
#
|
252
268
|
# # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
|
@@ -257,11 +273,14 @@ module ActionView
|
|
257
273
|
# # be stored in the trip variable in the departing attribute.
|
258
274
|
# datetime_select("trip", "departing", :default => 3.days.from_now)
|
259
275
|
#
|
276
|
+
# # Generate a datetime select with hours in the AM/PM format
|
277
|
+
# datetime_select("post", "written_on", :ampm => true)
|
278
|
+
#
|
260
279
|
# # Generates a datetime select that discards the type that, when POSTed, will be stored in the post variable
|
261
280
|
# # as the written_on attribute.
|
262
281
|
# datetime_select("post", "written_on", :discard_type => true)
|
263
282
|
#
|
264
|
-
# # Generates a datetime select with a custom prompt. Use
|
283
|
+
# # Generates a datetime select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
265
284
|
# datetime_select("post", "written_on", :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
266
285
|
# datetime_select("post", "written_on", :prompt => {:hour => true}) # generic prompt for hours
|
267
286
|
# datetime_select("post", "written_on", :prompt => true) # generic prompts for all
|
@@ -283,7 +302,7 @@ module ActionView
|
|
283
302
|
# ==== Examples
|
284
303
|
# my_date_time = Time.now + 4.days
|
285
304
|
#
|
286
|
-
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
305
|
+
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today).
|
287
306
|
# select_datetime(my_date_time)
|
288
307
|
#
|
289
308
|
# # Generates a datetime select that defaults to today (no specified datetime)
|
@@ -306,11 +325,14 @@ module ActionView
|
|
306
325
|
# # my_date_time (four days after today)
|
307
326
|
# select_datetime(my_date_time, :discard_type => true)
|
308
327
|
#
|
328
|
+
# # Generate a datetime field with hours in the AM/PM format
|
329
|
+
# select_datetime(my_date_time, :ampm => true)
|
330
|
+
#
|
309
331
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
310
332
|
# # prefixed with 'payday' rather than 'date'
|
311
333
|
# select_datetime(my_date_time, :prefix => 'payday')
|
312
334
|
#
|
313
|
-
# # Generates a datetime select with a custom prompt. Use
|
335
|
+
# # Generates a datetime select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
314
336
|
# select_datetime(my_date_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
315
337
|
# select_datetime(my_date_time, :prompt => {:hour => true}) # generic prompt for hours
|
316
338
|
# select_datetime(my_date_time, :prompt => true) # generic prompts for all
|
@@ -329,10 +351,10 @@ module ActionView
|
|
329
351
|
# ==== Examples
|
330
352
|
# my_date = Time.today + 6.days
|
331
353
|
#
|
332
|
-
# # Generates a date select that defaults to the date in my_date (six days
|
354
|
+
# # Generates a date select that defaults to the date in my_date (six days afteri today).
|
333
355
|
# select_date(my_date)
|
334
356
|
#
|
335
|
-
# # Generates a date select that defaults to today (no specified date)
|
357
|
+
# # Generates a date select that defaults to today (no specified date).
|
336
358
|
# select_date()
|
337
359
|
#
|
338
360
|
# # Generates a date select that defaults to the date in my_date (six days after today)
|
@@ -340,18 +362,18 @@ module ActionView
|
|
340
362
|
# select_date(my_date, :order => [:year, :month, :day])
|
341
363
|
#
|
342
364
|
# # Generates a date select that discards the type of the field and defaults to the date in
|
343
|
-
# # my_date (six days after today)
|
365
|
+
# # my_date (six days after today).
|
344
366
|
# select_date(my_date, :discard_type => true)
|
345
367
|
#
|
346
368
|
# # Generates a date select that defaults to the date in my_date,
|
347
|
-
# # which has fields separated by '/'
|
369
|
+
# # which has fields separated by '/'.
|
348
370
|
# select_date(my_date, :date_separator => '/')
|
349
371
|
#
|
350
372
|
# # Generates a date select that defaults to the datetime in my_date (six days after today)
|
351
|
-
# # prefixed with 'payday' rather than 'date'
|
373
|
+
# # prefixed with 'payday' rather than 'date'.
|
352
374
|
# select_date(my_date, :prefix => 'payday')
|
353
375
|
#
|
354
|
-
# # Generates a date select with a custom prompt. Use
|
376
|
+
# # Generates a date select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
355
377
|
# select_date(my_date, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
356
378
|
# select_date(my_date, :prompt => {:hour => true}) # generic prompt for hours
|
357
379
|
# select_date(my_date, :prompt => true) # generic prompts for all
|
@@ -360,7 +382,7 @@ module ActionView
|
|
360
382
|
DateTimeSelector.new(date, options, html_options).select_date
|
361
383
|
end
|
362
384
|
|
363
|
-
# Returns a set of html select-tags (one for hour and minute)
|
385
|
+
# Returns a set of html select-tags (one for hour and minute).
|
364
386
|
# You can set <tt>:time_separator</tt> key to format the output, and
|
365
387
|
# the <tt>:include_seconds</tt> option to include an input for seconds.
|
366
388
|
#
|
@@ -369,25 +391,28 @@ module ActionView
|
|
369
391
|
# ==== Examples
|
370
392
|
# my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
|
371
393
|
#
|
372
|
-
# # Generates a time select that defaults to the time in my_time
|
394
|
+
# # Generates a time select that defaults to the time in my_time.
|
373
395
|
# select_time(my_time)
|
374
396
|
#
|
375
|
-
# # Generates a time select that defaults to the current time (no specified time)
|
397
|
+
# # Generates a time select that defaults to the current time (no specified time).
|
376
398
|
# select_time()
|
377
399
|
#
|
378
400
|
# # Generates a time select that defaults to the time in my_time,
|
379
|
-
# # which has fields separated by ':'
|
401
|
+
# # which has fields separated by ':'.
|
380
402
|
# select_time(my_time, :time_separator => ':')
|
381
403
|
#
|
382
404
|
# # Generates a time select that defaults to the time in my_time,
|
383
|
-
# # that also includes an input for seconds
|
405
|
+
# # that also includes an input for seconds.
|
384
406
|
# select_time(my_time, :include_seconds => true)
|
385
407
|
#
|
386
408
|
# # Generates a time select that defaults to the time in my_time, that has fields
|
387
|
-
# # separated by ':' and includes an input for seconds
|
409
|
+
# # separated by ':' and includes an input for seconds.
|
388
410
|
# select_time(my_time, :time_separator => ':', :include_seconds => true)
|
389
411
|
#
|
390
|
-
# #
|
412
|
+
# # Generate a time select field with hours in the AM/PM format
|
413
|
+
# select_time(my_time, :ampm => true)
|
414
|
+
#
|
415
|
+
# # Generates a time select with a custom prompt. Use <tt>:prompt</tt> to true for generic prompts.
|
391
416
|
# select_time(my_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
392
417
|
# select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
|
393
418
|
# select_time(my_time, :prompt => true) # generic prompts for all
|
@@ -403,17 +428,17 @@ module ActionView
|
|
403
428
|
# ==== Examples
|
404
429
|
# my_time = Time.now + 16.minutes
|
405
430
|
#
|
406
|
-
# # Generates a select field for seconds that defaults to the seconds for the time in my_time
|
431
|
+
# # Generates a select field for seconds that defaults to the seconds for the time in my_time.
|
407
432
|
# select_second(my_time)
|
408
433
|
#
|
409
|
-
# # Generates a select field for seconds that defaults to the number given
|
434
|
+
# # Generates a select field for seconds that defaults to the number given.
|
410
435
|
# select_second(33)
|
411
436
|
#
|
412
437
|
# # Generates a select field for seconds that defaults to the seconds for the time in my_time
|
413
|
-
# # that is named 'interval' rather than 'second'
|
438
|
+
# # that is named 'interval' rather than 'second'.
|
414
439
|
# select_second(my_time, :field_name => 'interval')
|
415
440
|
#
|
416
|
-
# # Generates a select field for seconds with a custom prompt.
|
441
|
+
# # Generates a select field for seconds with a custom prompt. Use <tt>:prompt => true</tt> for a
|
417
442
|
# # generic prompt.
|
418
443
|
# select_minute(14, :prompt => 'Choose seconds')
|
419
444
|
#
|
@@ -429,17 +454,17 @@ module ActionView
|
|
429
454
|
# ==== Examples
|
430
455
|
# my_time = Time.now + 6.hours
|
431
456
|
#
|
432
|
-
# # Generates a select field for minutes that defaults to the minutes for the time in
|
457
|
+
# # Generates a select field for minutes that defaults to the minutes for the time in my_tiime.
|
433
458
|
# select_minute(my_time)
|
434
459
|
#
|
435
|
-
# # Generates a select field for minutes that defaults to the number given
|
460
|
+
# # Generates a select field for minutes that defaults to the number given.
|
436
461
|
# select_minute(14)
|
437
462
|
#
|
438
463
|
# # Generates a select field for minutes that defaults to the minutes for the time in my_time
|
439
|
-
# # that is named 'stride' rather than 'second'
|
464
|
+
# # that is named 'stride' rather than 'second'.
|
440
465
|
# select_minute(my_time, :field_name => 'stride')
|
441
466
|
#
|
442
|
-
# # Generates a select field for minutes with a custom prompt.
|
467
|
+
# # Generates a select field for minutes with a custom prompt. Use <tt>:prompt => true</tt> for a
|
443
468
|
# # generic prompt.
|
444
469
|
# select_minute(14, :prompt => 'Choose minutes')
|
445
470
|
#
|
@@ -454,20 +479,23 @@ module ActionView
|
|
454
479
|
# ==== Examples
|
455
480
|
# my_time = Time.now + 6.hours
|
456
481
|
#
|
457
|
-
# # Generates a select field for hours that defaults to the hour for the time in my_time
|
482
|
+
# # Generates a select field for hours that defaults to the hour for the time in my_time.
|
458
483
|
# select_hour(my_time)
|
459
484
|
#
|
460
|
-
# # Generates a select field for hours that defaults to the number given
|
485
|
+
# # Generates a select field for hours that defaults to the number given.
|
461
486
|
# select_hour(13)
|
462
487
|
#
|
463
488
|
# # Generates a select field for hours that defaults to the minutes for the time in my_time
|
464
|
-
# # that is named 'stride' rather than 'second'
|
489
|
+
# # that is named 'stride' rather than 'second'.
|
465
490
|
# select_hour(my_time, :field_name => 'stride')
|
466
491
|
#
|
467
|
-
# # Generates a select field for hours with a custom prompt.
|
492
|
+
# # Generates a select field for hours with a custom prompt. Use <tt>:prompt => true</tt> for a
|
468
493
|
# # generic prompt.
|
469
494
|
# select_hour(13, :prompt => 'Choose hour')
|
470
495
|
#
|
496
|
+
# # Generate a select field for hours in the AM/PM format
|
497
|
+
# select_hour(my_time, :ampm => true)
|
498
|
+
#
|
471
499
|
def select_hour(datetime, options = {}, html_options = {})
|
472
500
|
DateTimeSelector.new(datetime, options, html_options).select_hour
|
473
501
|
end
|
@@ -479,17 +507,17 @@ module ActionView
|
|
479
507
|
# ==== Examples
|
480
508
|
# my_date = Time.today + 2.days
|
481
509
|
#
|
482
|
-
# # Generates a select field for days that defaults to the day for the date in my_date
|
510
|
+
# # Generates a select field for days that defaults to the day for the date in my_date.
|
483
511
|
# select_day(my_time)
|
484
512
|
#
|
485
|
-
# # Generates a select field for days that defaults to the number given
|
513
|
+
# # Generates a select field for days that defaults to the number given.
|
486
514
|
# select_day(5)
|
487
515
|
#
|
488
516
|
# # Generates a select field for days that defaults to the day for the date in my_date
|
489
|
-
# # that is named 'due' rather than 'day'
|
517
|
+
# # that is named 'due' rather than 'day'.
|
490
518
|
# select_day(my_time, :field_name => 'due')
|
491
519
|
#
|
492
|
-
# # Generates a select field for days with a custom prompt. Use
|
520
|
+
# # Generates a select field for days with a custom prompt. Use <tt>:prompt => true</tt> for a
|
493
521
|
# # generic prompt.
|
494
522
|
# select_day(5, :prompt => 'Choose day')
|
495
523
|
#
|
@@ -512,7 +540,7 @@ module ActionView
|
|
512
540
|
# select_month(Date.today)
|
513
541
|
#
|
514
542
|
# # Generates a select field for months that defaults to the current month that
|
515
|
-
# # is named "start" rather than "month"
|
543
|
+
# # is named "start" rather than "month".
|
516
544
|
# select_month(Date.today, :field_name => 'start')
|
517
545
|
#
|
518
546
|
# # Generates a select field for months that defaults to the current month that
|
@@ -531,7 +559,7 @@ module ActionView
|
|
531
559
|
# # will use keys like "Januar", "Marts."
|
532
560
|
# select_month(Date.today, :use_month_names => %w(Januar Februar Marts ...))
|
533
561
|
#
|
534
|
-
# # Generates a select field for months with a custom prompt.
|
562
|
+
# # Generates a select field for months with a custom prompt. Use <tt>:prompt => true</tt> for a
|
535
563
|
# # generic prompt.
|
536
564
|
# select_month(14, :prompt => 'Choose month')
|
537
565
|
#
|
@@ -547,22 +575,22 @@ module ActionView
|
|
547
575
|
#
|
548
576
|
# ==== Examples
|
549
577
|
# # Generates a select field for years that defaults to the current year that
|
550
|
-
# # has ascending year values
|
578
|
+
# # has ascending year values.
|
551
579
|
# select_year(Date.today, :start_year => 1992, :end_year => 2007)
|
552
580
|
#
|
553
581
|
# # Generates a select field for years that defaults to the current year that
|
554
|
-
# # is named 'birth' rather than 'year'
|
582
|
+
# # is named 'birth' rather than 'year'.
|
555
583
|
# select_year(Date.today, :field_name => 'birth')
|
556
584
|
#
|
557
585
|
# # Generates a select field for years that defaults to the current year that
|
558
|
-
# # has descending year values
|
586
|
+
# # has descending year values.
|
559
587
|
# select_year(Date.today, :start_year => 2005, :end_year => 1900)
|
560
588
|
#
|
561
589
|
# # Generates a select field for years that defaults to the year 2006 that
|
562
|
-
# # has ascending year values
|
590
|
+
# # has ascending year values.
|
563
591
|
# select_year(2006, :start_year => 2000, :end_year => 2010)
|
564
592
|
#
|
565
|
-
# # Generates a select field for years with a custom prompt.
|
593
|
+
# # Generates a select field for years with a custom prompt. Use <tt>:prompt => true</tt> for a
|
566
594
|
# # generic prompt.
|
567
595
|
# select_year(14, :prompt => 'Choose year')
|
568
596
|
#
|
@@ -601,6 +629,15 @@ module ActionView
|
|
601
629
|
:year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
|
602
630
|
}.freeze
|
603
631
|
|
632
|
+
AMPM_TRANSLATION = Hash[
|
633
|
+
[[0, "12 AM"], [1, "01 AM"], [2, "02 AM"], [3, "03 AM"],
|
634
|
+
[4, "04 AM"], [5, "05 AM"], [6, "06 AM"], [7, "07 AM"],
|
635
|
+
[8, "08 AM"], [9, "09 AM"], [10, "10 AM"], [11, "11 AM"],
|
636
|
+
[12, "12 PM"], [13, "01 PM"], [14, "02 PM"], [15, "03 PM"],
|
637
|
+
[16, "04 PM"], [17, "05 PM"], [18, "06 PM"], [19, "07 PM"],
|
638
|
+
[20, "08 PM"], [21, "09 PM"], [22, "10 PM"], [23, "11 PM"]]
|
639
|
+
].freeze
|
640
|
+
|
604
641
|
def initialize(datetime, options = {}, html_options = {})
|
605
642
|
@options = options.dup
|
606
643
|
@html_options = html_options.dup
|
@@ -692,7 +729,7 @@ module ActionView
|
|
692
729
|
if @options[:use_hidden] || @options[:discard_hour]
|
693
730
|
build_hidden(:hour, hour)
|
694
731
|
else
|
695
|
-
build_options_and_select(:hour, hour, :end => 23)
|
732
|
+
build_options_and_select(:hour, hour, :end => 23, :ampm => @options[:ampm])
|
696
733
|
end
|
697
734
|
end
|
698
735
|
|
@@ -747,7 +784,7 @@ module ActionView
|
|
747
784
|
end
|
748
785
|
|
749
786
|
# Returns translated month names, but also ensures that a custom month
|
750
|
-
# name array has a leading nil element
|
787
|
+
# name array has a leading nil element.
|
751
788
|
def month_names
|
752
789
|
month_names = @options[:use_month_names] || translated_month_names
|
753
790
|
month_names.unshift(nil) if month_names.size < 13
|
@@ -755,13 +792,13 @@ module ActionView
|
|
755
792
|
end
|
756
793
|
memoize :month_names
|
757
794
|
|
758
|
-
# Returns translated month names
|
795
|
+
# Returns translated month names.
|
759
796
|
# => [nil, "January", "February", "March",
|
760
797
|
# "April", "May", "June", "July",
|
761
798
|
# "August", "September", "October",
|
762
799
|
# "November", "December"]
|
763
800
|
#
|
764
|
-
# If
|
801
|
+
# If <tt>:use_short_month</tt> option is set
|
765
802
|
# => [nil, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
766
803
|
# "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
767
804
|
def translated_month_names
|
@@ -769,13 +806,13 @@ module ActionView
|
|
769
806
|
I18n.translate(key, :locale => @options[:locale])
|
770
807
|
end
|
771
808
|
|
772
|
-
# Lookup month name for number
|
809
|
+
# Lookup month name for number.
|
773
810
|
# month_name(1) => "January"
|
774
811
|
#
|
775
|
-
# If
|
812
|
+
# If <tt>:use_month_numbers</tt> option is passed
|
776
813
|
# month_name(1) => 1
|
777
814
|
#
|
778
|
-
# If
|
815
|
+
# If <tt>:add_month_numbers</tt> option is passed
|
779
816
|
# month_name(1) => "1 - January"
|
780
817
|
def month_name(number)
|
781
818
|
if @options[:use_month_numbers]
|
@@ -796,21 +833,27 @@ module ActionView
|
|
796
833
|
I18n.translate(:'date.order', :locale => @options[:locale]) || []
|
797
834
|
end
|
798
835
|
|
799
|
-
# Build full select tag from date type and options
|
836
|
+
# Build full select tag from date type and options.
|
800
837
|
def build_options_and_select(type, selected, options = {})
|
801
838
|
build_select(type, build_options(selected, options))
|
802
839
|
end
|
803
840
|
|
804
|
-
# Build select option html from date value and options
|
841
|
+
# Build select option html from date value and options.
|
805
842
|
# build_options(15, :start => 1, :end => 31)
|
806
843
|
# => "<option value="1">1</option>
|
807
|
-
# <option value
|
808
|
-
# <option value
|
844
|
+
# <option value="2">2</option>
|
845
|
+
# <option value="3">3</option>..."
|
846
|
+
#
|
847
|
+
# If <tt>:step</tt> options is passed
|
848
|
+
# build_options(15, :start => 1, :end => 31, :step => 2)
|
849
|
+
# => "<option value="1">1</option>
|
850
|
+
# <option value="3">3</option>
|
851
|
+
# <option value="5">5</option>..."
|
809
852
|
def build_options(selected, options = {})
|
810
853
|
start = options.delete(:start) || 0
|
811
854
|
stop = options.delete(:end) || 59
|
812
855
|
step = options.delete(:step) || 1
|
813
|
-
options.reverse_merge!({:leading_zeros => true})
|
856
|
+
options.reverse_merge!({:leading_zeros => true, :ampm => false})
|
814
857
|
leading_zeros = options.delete(:leading_zeros)
|
815
858
|
|
816
859
|
select_options = []
|
@@ -818,12 +861,13 @@ module ActionView
|
|
818
861
|
value = leading_zeros ? sprintf("%02d", i) : i
|
819
862
|
tag_options = { :value => value }
|
820
863
|
tag_options[:selected] = "selected" if selected == i
|
821
|
-
|
864
|
+
text = options[:ampm] ? AMPM_TRANSLATION[i] : value
|
865
|
+
select_options << content_tag(:option, text, tag_options)
|
822
866
|
end
|
823
867
|
(select_options.join("\n") + "\n").html_safe
|
824
868
|
end
|
825
869
|
|
826
|
-
# Builds select tag from date type and html select options
|
870
|
+
# Builds select tag from date type and html select options.
|
827
871
|
# build_select(:month, "<option value="1">January</option>...")
|
828
872
|
# => "<select id="post_written_on_2i" name="post[written_on(2i)]">
|
829
873
|
# <option value="1">January</option>...
|
@@ -843,7 +887,7 @@ module ActionView
|
|
843
887
|
(content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe
|
844
888
|
end
|
845
889
|
|
846
|
-
# Builds a prompt option tag with supplied options or from default options
|
890
|
+
# Builds a prompt option tag with supplied options or from default options.
|
847
891
|
# prompt_option_tag(:month, :prompt => 'Select month')
|
848
892
|
# => "<option value="">Select month</option>"
|
849
893
|
def prompt_option_tag(type, options)
|
@@ -860,7 +904,7 @@ module ActionView
|
|
860
904
|
prompt ? content_tag(:option, prompt, :value => '') : ''
|
861
905
|
end
|
862
906
|
|
863
|
-
# Builds hidden input tag for date part and value
|
907
|
+
# Builds hidden input tag for date part and value.
|
864
908
|
# build_hidden(:year, 2008)
|
865
909
|
# => "<input id="post_written_on_1i" name="post[written_on(1i)]" type="hidden" value="2008" />"
|
866
910
|
def build_hidden(type, value)
|
@@ -872,7 +916,7 @@ module ActionView
|
|
872
916
|
}.merge(@html_options.slice(:disabled))) + "\n").html_safe
|
873
917
|
end
|
874
918
|
|
875
|
-
# Returns the name attribute for the input tag
|
919
|
+
# Returns the name attribute for the input tag.
|
876
920
|
# => post[written_on(1i)]
|
877
921
|
def input_name_from_type(type)
|
878
922
|
prefix = @options[:prefix] || ActionView::Helpers::DateTimeSelector::DEFAULT_PREFIX
|
@@ -886,7 +930,7 @@ module ActionView
|
|
886
930
|
@options[:discard_type] ? prefix : "#{prefix}[#{field_name}]"
|
887
931
|
end
|
888
932
|
|
889
|
-
# Returns the id attribute for the input tag
|
933
|
+
# Returns the id attribute for the input tag.
|
890
934
|
# => "post_written_on_1i"
|
891
935
|
def input_id_from_type(type)
|
892
936
|
input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
|
@@ -903,7 +947,7 @@ module ActionView
|
|
903
947
|
select.html_safe
|
904
948
|
end
|
905
949
|
|
906
|
-
# Returns the separator for a given datetime component
|
950
|
+
# Returns the separator for a given datetime component.
|
907
951
|
def separator(type)
|
908
952
|
case type
|
909
953
|
when :year
|