actionpack 3.2.22.5 → 4.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
1
|
require 'active_support/core_ext/string/output_safety'
|
3
2
|
|
4
3
|
module ActionView
|
@@ -13,7 +12,6 @@ module ActionView
|
|
13
12
|
# The capture method allows you to extract part of a template into a
|
14
13
|
# variable. You can then use this variable anywhere in your templates or layout.
|
15
14
|
#
|
16
|
-
# ==== Examples
|
17
15
|
# The capture method can be used in ERB templates...
|
18
16
|
#
|
19
17
|
# <% @greeting = capture do %>
|
@@ -44,14 +42,12 @@ module ActionView
|
|
44
42
|
end
|
45
43
|
|
46
44
|
# Calling content_for stores a block of markup in an identifier for later use.
|
47
|
-
#
|
48
|
-
# or the layout
|
45
|
+
# In order to access this stored content in other templates, helper modules
|
46
|
+
# or the layout, you would pass the identifier as an argument to <tt>content_for</tt>.
|
49
47
|
#
|
50
48
|
# Note: <tt>yield</tt> can still be used to retrieve the stored content, but calling
|
51
49
|
# <tt>yield</tt> doesn't work in helper modules, while <tt>content_for</tt> does.
|
52
50
|
#
|
53
|
-
# ==== Examples
|
54
|
-
#
|
55
51
|
# <% content_for :not_authorized do %>
|
56
52
|
# alert('You are not authorized to do that!')
|
57
53
|
# <% end %>
|
@@ -76,13 +72,14 @@ module ActionView
|
|
76
72
|
#
|
77
73
|
# <%= stored_content %>
|
78
74
|
#
|
79
|
-
# You can use the <tt>yield</tt> syntax alongside an existing call to
|
75
|
+
# You can also use the <tt>yield</tt> syntax alongside an existing call to
|
76
|
+
# <tt>yield</tt> in a layout. For example:
|
80
77
|
#
|
81
78
|
# <%# This is the layout %>
|
82
79
|
# <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
83
80
|
# <head>
|
84
|
-
#
|
85
|
-
#
|
81
|
+
# <title>My Website</title>
|
82
|
+
# <%= yield :script %>
|
86
83
|
# </head>
|
87
84
|
# <body>
|
88
85
|
# <%= yield %>
|
@@ -96,12 +93,12 @@ module ActionView
|
|
96
93
|
# Please login!
|
97
94
|
#
|
98
95
|
# <% content_for :script do %>
|
99
|
-
# <script
|
96
|
+
# <script>alert('You are not authorized to view this page!')</script>
|
100
97
|
# <% end %>
|
101
98
|
#
|
102
99
|
# Then, in another view, you could to do something like this:
|
103
100
|
#
|
104
|
-
# <%= link_to 'Logout', :
|
101
|
+
# <%= link_to 'Logout', action: 'logout', remote: true %>
|
105
102
|
#
|
106
103
|
# <% content_for :script do %>
|
107
104
|
# <%= javascript_include_tag :defaults %>
|
@@ -110,33 +107,53 @@ module ActionView
|
|
110
107
|
# That will place +script+ tags for your default set of JavaScript files on the page;
|
111
108
|
# this technique is useful if you'll only be using these scripts in a few views.
|
112
109
|
#
|
113
|
-
# Note that content_for concatenates the blocks it is given for a particular
|
110
|
+
# Note that content_for concatenates (default) the blocks it is given for a particular
|
114
111
|
# identifier in order. For example:
|
115
112
|
#
|
116
113
|
# <% content_for :navigation do %>
|
117
|
-
# <li><%= link_to 'Home', :
|
114
|
+
# <li><%= link_to 'Home', action: 'index' %></li>
|
118
115
|
# <% end %>
|
119
116
|
#
|
120
|
-
#
|
117
|
+
# And in other place:
|
121
118
|
#
|
122
119
|
# <% content_for :navigation do %>
|
123
|
-
# <li><%= link_to 'Login', :
|
120
|
+
# <li><%= link_to 'Login', action: 'login' %></li>
|
124
121
|
# <% end %>
|
125
122
|
#
|
126
123
|
# Then, in another template or layout, this code would render both links in order:
|
127
124
|
#
|
128
125
|
# <ul><%= content_for :navigation %></ul>
|
129
126
|
#
|
127
|
+
# If the flush parameter is true content_for replaces the blocks it is given. For example:
|
128
|
+
#
|
129
|
+
# <% content_for :navigation do %>
|
130
|
+
# <li><%= link_to 'Home', action: 'index' %></li>
|
131
|
+
# <% end %>
|
132
|
+
#
|
133
|
+
# <%# Add some other content, or use a different template: %>
|
134
|
+
#
|
135
|
+
# <% content_for :navigation, flush: true do %>
|
136
|
+
# <li><%= link_to 'Login', action: 'login' %></li>
|
137
|
+
# <% end %>
|
138
|
+
#
|
139
|
+
# Then, in another template or layout, this code would render only the last link:
|
140
|
+
#
|
141
|
+
# <ul><%= content_for :navigation %></ul>
|
142
|
+
#
|
130
143
|
# Lastly, simple content can be passed as a parameter:
|
131
144
|
#
|
132
145
|
# <% content_for :script, javascript_include_tag(:defaults) %>
|
133
146
|
#
|
134
|
-
# WARNING: content_for is ignored in caches. So you shouldn't use it
|
135
|
-
|
136
|
-
def content_for(name, content = nil, &block)
|
147
|
+
# WARNING: content_for is ignored in caches. So you shouldn't use it for elements that will be fragment cached.
|
148
|
+
def content_for(name, content = nil, options = {}, &block)
|
137
149
|
if content || block_given?
|
138
|
-
|
139
|
-
|
150
|
+
if block_given?
|
151
|
+
options = content if content
|
152
|
+
content = capture(&block)
|
153
|
+
end
|
154
|
+
if content
|
155
|
+
options[:flush] ? @view_flow.set(name, content) : @view_flow.append(name, content)
|
156
|
+
end
|
140
157
|
nil
|
141
158
|
else
|
142
159
|
@view_flow.get(name)
|
@@ -154,18 +171,14 @@ module ActionView
|
|
154
171
|
result unless content
|
155
172
|
end
|
156
173
|
|
157
|
-
# content_for?
|
174
|
+
# content_for? checks whether any content has been captured yet using `content_for`.
|
158
175
|
# Useful to render parts of your layout differently based on what is in your views.
|
159
176
|
#
|
160
|
-
# ==== Examples
|
161
|
-
#
|
162
|
-
# Perhaps you will use different css in you layout if no content_for :right_column
|
163
|
-
#
|
164
177
|
# <%# This is the layout %>
|
165
178
|
# <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
166
179
|
# <head>
|
167
|
-
#
|
168
|
-
#
|
180
|
+
# <title>My Website</title>
|
181
|
+
# <%= yield :script %>
|
169
182
|
# </head>
|
170
183
|
# <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
|
171
184
|
# <%= yield %>
|
@@ -181,7 +194,7 @@ module ActionView
|
|
181
194
|
def with_output_buffer(buf = nil) #:nodoc:
|
182
195
|
unless buf
|
183
196
|
buf = ActionView::OutputBuffer.new
|
184
|
-
buf.force_encoding(output_buffer.encoding) if output_buffer
|
197
|
+
buf.force_encoding(output_buffer.encoding) if output_buffer
|
185
198
|
end
|
186
199
|
self.output_buffer, old_buffer = buf, output_buffer
|
187
200
|
yield
|
@@ -193,7 +206,7 @@ module ActionView
|
|
193
206
|
# Add the output buffer to the response body and start a new one.
|
194
207
|
def flush_output_buffer #:nodoc:
|
195
208
|
if output_buffer && !output_buffer.empty?
|
196
|
-
response.
|
209
|
+
response.stream.write output_buffer
|
197
210
|
self.output_buffer = output_buffer.respond_to?(:clone_empty) ? output_buffer.clone_empty : output_buffer[0, 0]
|
198
211
|
nil
|
199
212
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'action_view/helpers/tag_helper'
|
3
|
+
require 'active_support/core_ext/array/extract_options'
|
3
4
|
require 'active_support/core_ext/date/conversions'
|
4
5
|
require 'active_support/core_ext/hash/slice'
|
5
6
|
require 'active_support/core_ext/object/with_options'
|
@@ -12,14 +13,14 @@ module ActionView
|
|
12
13
|
# elements. All of the select-type methods share a number of common options that are as follows:
|
13
14
|
#
|
14
15
|
# * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
|
15
|
-
#
|
16
|
+
# would give \birthday[month] instead of \date[month] if passed to the <tt>select_month</tt> method.
|
16
17
|
# * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
|
17
18
|
# * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true,
|
18
19
|
# the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
|
19
|
-
# of
|
20
|
+
# of \date[month].
|
20
21
|
module DateHelper
|
21
22
|
# Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
|
22
|
-
#
|
23
|
+
# Pass <tt>include_seconds: true</tt> if you want more detailed approximations when distance < 1 min, 29 secs.
|
23
24
|
# Distances are reported based on the following table:
|
24
25
|
#
|
25
26
|
# 0 <-> 29 secs # => less than a minute
|
@@ -29,14 +30,15 @@ module ActionView
|
|
29
30
|
# 89 mins, 30 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours
|
30
31
|
# 23 hrs, 59 mins, 30 secs <-> 41 hrs, 59 mins, 29 secs # => 1 day
|
31
32
|
# 41 hrs, 59 mins, 30 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days
|
32
|
-
# 29 days, 23 hrs, 59 mins, 30 secs <->
|
33
|
+
# 29 days, 23 hrs, 59 mins, 30 secs <-> 44 days, 23 hrs, 59 mins, 29 secs # => about 1 month
|
34
|
+
# 44 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 2 months
|
33
35
|
# 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months
|
34
36
|
# 1 yr <-> 1 yr, 3 months # => about 1 year
|
35
37
|
# 1 yr, 3 months <-> 1 yr, 9 months # => over 1 year
|
36
38
|
# 1 yr, 9 months <-> 2 yr minus 1 sec # => almost 2 years
|
37
39
|
# 2 yrs <-> max time or date # => (same rules as 1 yr)
|
38
40
|
#
|
39
|
-
# With <tt>include_seconds</tt>
|
41
|
+
# With <tt>include_seconds: true</tt> and the difference < 1 minute 29 seconds:
|
40
42
|
# 0-4 secs # => less than 5 seconds
|
41
43
|
# 5-9 secs # => less than 10 seconds
|
42
44
|
# 10-19 secs # => less than 20 seconds
|
@@ -44,43 +46,49 @@ module ActionView
|
|
44
46
|
# 40-59 secs # => less than a minute
|
45
47
|
# 60-89 secs # => 1 minute
|
46
48
|
#
|
47
|
-
# ==== Examples
|
48
49
|
# from_time = Time.now
|
49
|
-
# distance_of_time_in_words(from_time, from_time + 50.minutes)
|
50
|
-
# distance_of_time_in_words(from_time, 50.minutes.from_now)
|
51
|
-
# distance_of_time_in_words(from_time, from_time + 15.seconds)
|
52
|
-
# distance_of_time_in_words(from_time, from_time + 15.seconds, true)
|
53
|
-
# distance_of_time_in_words(from_time, 3.years.from_now)
|
54
|
-
# distance_of_time_in_words(from_time, from_time + 60.hours)
|
55
|
-
# distance_of_time_in_words(from_time, from_time + 45.seconds, true)
|
56
|
-
# distance_of_time_in_words(from_time, from_time - 45.seconds, true)
|
57
|
-
# distance_of_time_in_words(from_time, 76.seconds.from_now)
|
58
|
-
# distance_of_time_in_words(from_time, from_time + 1.year + 3.days)
|
59
|
-
# distance_of_time_in_words(from_time, from_time + 3.years + 6.months)
|
50
|
+
# distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour
|
51
|
+
# distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour
|
52
|
+
# distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute
|
53
|
+
# distance_of_time_in_words(from_time, from_time + 15.seconds, include_seconds: true) # => less than 20 seconds
|
54
|
+
# distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years
|
55
|
+
# distance_of_time_in_words(from_time, from_time + 60.hours) # => 3 days
|
56
|
+
# distance_of_time_in_words(from_time, from_time + 45.seconds, include_seconds: true) # => less than a minute
|
57
|
+
# distance_of_time_in_words(from_time, from_time - 45.seconds, include_seconds: true) # => less than a minute
|
58
|
+
# distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute
|
59
|
+
# distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year
|
60
|
+
# distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years
|
60
61
|
# distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years
|
61
62
|
#
|
62
63
|
# to_time = Time.now + 6.years + 19.days
|
63
|
-
# distance_of_time_in_words(from_time, to_time, true)
|
64
|
-
# distance_of_time_in_words(to_time, from_time, true)
|
65
|
-
# distance_of_time_in_words(Time.now, Time.now)
|
66
|
-
|
67
|
-
|
64
|
+
# distance_of_time_in_words(from_time, to_time, include_seconds: true) # => about 6 years
|
65
|
+
# distance_of_time_in_words(to_time, from_time, include_seconds: true) # => about 6 years
|
66
|
+
# distance_of_time_in_words(Time.now, Time.now) # => less than a minute
|
67
|
+
def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
|
68
|
+
if include_seconds_or_options.is_a?(Hash)
|
69
|
+
options = include_seconds_or_options
|
70
|
+
else
|
71
|
+
ActiveSupport::Deprecation.warn "distance_of_time_in_words and time_ago_in_words now accept :include_seconds " +
|
72
|
+
"as a part of options hash, not a boolean argument"
|
73
|
+
options[:include_seconds] ||= !!include_seconds_or_options
|
74
|
+
end
|
75
|
+
|
68
76
|
options = {
|
69
|
-
:
|
77
|
+
scope: :'datetime.distance_in_words'
|
70
78
|
}.merge!(options)
|
71
79
|
|
72
80
|
from_time = from_time.to_time if from_time.respond_to?(:to_time)
|
73
81
|
to_time = to_time.to_time if to_time.respond_to?(:to_time)
|
74
|
-
|
75
|
-
distance_in_minutes = (
|
76
|
-
distance_in_seconds =
|
82
|
+
from_time, to_time = to_time, from_time if from_time > to_time
|
83
|
+
distance_in_minutes = ((to_time - from_time)/60.0).round
|
84
|
+
distance_in_seconds = (to_time - from_time).round
|
77
85
|
|
78
86
|
I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale|
|
79
87
|
case distance_in_minutes
|
80
88
|
when 0..1
|
81
89
|
return distance_in_minutes == 0 ?
|
82
90
|
locale.t(:less_than_x_minutes, :count => 1) :
|
83
|
-
locale.t(:x_minutes, :count => distance_in_minutes) unless include_seconds
|
91
|
+
locale.t(:x_minutes, :count => distance_in_minutes) unless options[:include_seconds]
|
84
92
|
|
85
93
|
case distance_in_seconds
|
86
94
|
when 0..4 then locale.t :less_than_x_seconds, :count => 5
|
@@ -91,26 +99,35 @@ module ActionView
|
|
91
99
|
else locale.t :x_minutes, :count => 1
|
92
100
|
end
|
93
101
|
|
94
|
-
when 2
|
95
|
-
when 45
|
96
|
-
|
97
|
-
when 1440
|
98
|
-
|
99
|
-
when
|
100
|
-
|
102
|
+
when 2...45 then locale.t :x_minutes, :count => distance_in_minutes
|
103
|
+
when 45...90 then locale.t :about_x_hours, :count => 1
|
104
|
+
# 90 mins up to 24 hours
|
105
|
+
when 90...1440 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round
|
106
|
+
# 24 hours up to 42 hours
|
107
|
+
when 1440...2520 then locale.t :x_days, :count => 1
|
108
|
+
# 42 hours up to 30 days
|
109
|
+
when 2520...43200 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round
|
110
|
+
# 30 days up to 60 days
|
111
|
+
when 43200...86400 then locale.t :about_x_months, :count => (distance_in_minutes.to_f / 43200.0).round
|
112
|
+
# 60 days up to 365 days
|
113
|
+
when 86400...525600 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
|
101
114
|
else
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
if from_time.acts_like?(:time) && to_time.acts_like?(:time)
|
116
|
+
fyear = from_time.year
|
117
|
+
fyear += 1 if from_time.month >= 3
|
118
|
+
tyear = to_time.year
|
119
|
+
tyear -= 1 if to_time.month < 3
|
120
|
+
leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
|
121
|
+
minute_offset_for_leap_year = leap_years * 1440
|
122
|
+
# Discount the leap year days when calculating year distance.
|
123
|
+
# e.g. if there are 20 leap year days between 2 dates having the same day
|
124
|
+
# and month then the based on 365 days calculation
|
125
|
+
# the distance in years will come out to over 80 years when in written
|
126
|
+
# english it would read better as about 80 years.
|
127
|
+
minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
|
128
|
+
else
|
129
|
+
minutes_with_offset = distance_in_minutes
|
130
|
+
end
|
114
131
|
remainder = (minutes_with_offset % 525600)
|
115
132
|
distance_in_years = (minutes_with_offset.div 525600)
|
116
133
|
if remainder < 131400
|
@@ -126,16 +143,22 @@ module ActionView
|
|
126
143
|
|
127
144
|
# Like <tt>distance_of_time_in_words</tt>, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
|
128
145
|
#
|
129
|
-
#
|
130
|
-
# time_ago_in_words(3.minutes.
|
131
|
-
# time_ago_in_words(Time.now - 15.hours)
|
132
|
-
# time_ago_in_words(Time.now)
|
146
|
+
# time_ago_in_words(3.minutes.from_now) # => 3 minutes
|
147
|
+
# time_ago_in_words(3.minutes.ago) # => 3 minutes
|
148
|
+
# time_ago_in_words(Time.now - 15.hours) # => about 15 hours
|
149
|
+
# time_ago_in_words(Time.now) # => less than a minute
|
150
|
+
# time_ago_in_words(Time.now, include_seconds: true) # => less than 5 seconds
|
133
151
|
#
|
134
152
|
# from_time = Time.now - 3.days - 14.minutes - 25.seconds
|
135
153
|
# time_ago_in_words(from_time) # => 3 days
|
136
154
|
#
|
137
|
-
|
138
|
-
|
155
|
+
# from_time = (3.days + 14.minutes + 25.seconds).ago
|
156
|
+
# time_ago_in_words(from_time) # => 3 days
|
157
|
+
#
|
158
|
+
# Note that you cannot pass a <tt>Numeric</tt> value to <tt>time_ago_in_words</tt>.
|
159
|
+
#
|
160
|
+
def time_ago_in_words(from_time, include_seconds_or_options = {})
|
161
|
+
distance_of_time_in_words(from_time, Time.now, include_seconds_or_options)
|
139
162
|
end
|
140
163
|
|
141
164
|
alias_method :distance_of_time_in_words_to_now, :time_ago_in_words
|
@@ -143,10 +166,11 @@ module ActionView
|
|
143
166
|
# Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based
|
144
167
|
# attribute (identified by +method+) on an object assigned to the template (identified by +object+).
|
145
168
|
#
|
146
|
-
#
|
147
169
|
# ==== Options
|
148
170
|
# * <tt>:use_month_numbers</tt> - Set to true if you want to use month numbers rather than month names (e.g.
|
149
171
|
# "2" instead of "February").
|
172
|
+
# * <tt>:use_two_digit_numbers</tt> - Set to true if you want to display two digit month and day numbers (e.g.
|
173
|
+
# "02" instead of "February" and "08" instead of "8").
|
150
174
|
# * <tt>:use_short_month</tt> - Set to true if you want to use abbreviated month names instead of full
|
151
175
|
# month names (e.g. "Feb" instead of "February").
|
152
176
|
# * <tt>:add_month_numbers</tt> - Set to true if you want to use both month numbers and month names (e.g.
|
@@ -165,60 +189,70 @@ module ActionView
|
|
165
189
|
# as a hidden field instead of showing a select field.
|
166
190
|
# * <tt>:order</tt> - Set to an array containing <tt>:day</tt>, <tt>:month</tt> and <tt>:year</tt> to
|
167
191
|
# customize the order in which the select fields are shown. If you leave out any of the symbols, the respective
|
168
|
-
# select will not be shown (like when you set <tt
|
192
|
+
# select will not be shown (like when you set <tt>discard_xxx: true</tt>. Defaults to the order defined in
|
169
193
|
# the respective locale (e.g. [:year, :month, :day] in the en locale that ships with Rails).
|
170
194
|
# * <tt>:include_blank</tt> - Include a blank option in every select field so it's possible to set empty
|
171
195
|
# dates.
|
172
196
|
# * <tt>:default</tt> - Set a default date if the affected date isn't set or is nil.
|
197
|
+
# * <tt>:selected</tt> - Set a date that overrides the actual value.
|
173
198
|
# * <tt>:disabled</tt> - Set to true if you want show the select fields as disabled.
|
174
199
|
# * <tt>:prompt</tt> - Set to true (for a generic prompt), a prompt string or a hash of prompt strings
|
175
200
|
# for <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:minute</tt> and <tt>:second</tt>.
|
176
201
|
# Setting this option prepends a select option with a generic prompt (Day, Month, Year, Hour, Minute, Seconds)
|
177
202
|
# or the given prompt string.
|
203
|
+
# * <tt>:with_css_classes</tt> - Set to true if you want assign different styles for 'select' tags. This option
|
204
|
+
# automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags.
|
178
205
|
#
|
179
206
|
# If anything is passed in the +html_options+ hash it will be applied to every select tag in the set.
|
180
207
|
#
|
181
208
|
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
|
182
209
|
#
|
183
|
-
# ==== Examples
|
184
210
|
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
|
185
211
|
# date_select("article", "written_on")
|
186
212
|
#
|
187
213
|
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
|
188
214
|
# # with the year in the year drop down box starting at 1995.
|
189
|
-
# date_select("article", "written_on", :
|
215
|
+
# date_select("article", "written_on", start_year: 1995)
|
190
216
|
#
|
191
217
|
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
|
192
218
|
# # with the year in the year drop down box starting at 1995, numbers used for months instead of words,
|
193
219
|
# # and without a day select box.
|
194
|
-
# date_select("article", "written_on", :
|
195
|
-
# :
|
220
|
+
# date_select("article", "written_on", start_year: 1995, use_month_numbers: true,
|
221
|
+
# discard_day: true, include_blank: true)
|
222
|
+
#
|
223
|
+
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute,
|
224
|
+
# # with two digit numbers used for months and days.
|
225
|
+
# date_select("article", "written_on", use_two_digit_numbers: true)
|
196
226
|
#
|
197
227
|
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
|
198
228
|
# # with the fields ordered as day, month, year rather than month, day, year.
|
199
|
-
# date_select("article", "written_on", :
|
229
|
+
# date_select("article", "written_on", order: [:day, :month, :year])
|
200
230
|
#
|
201
231
|
# # Generates a date select that when POSTed is stored in the user variable, in the birthday attribute
|
202
232
|
# # lacking a year field.
|
203
|
-
# date_select("user", "birthday", :
|
233
|
+
# date_select("user", "birthday", order: [:month, :day])
|
204
234
|
#
|
205
235
|
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
|
206
236
|
# # which is initially set to the date 3 days from the current date
|
207
|
-
# date_select("article", "written_on", :
|
237
|
+
# date_select("article", "written_on", default: 3.days.from_now)
|
238
|
+
#
|
239
|
+
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute
|
240
|
+
# # which is set in the form with todays date, regardless of the value in the Active Record object.
|
241
|
+
# date_select("article", "written_on", selected: Date.today)
|
208
242
|
#
|
209
243
|
# # Generates a date select that when POSTed is stored in the credit_card variable, in the bill_due attribute
|
210
244
|
# # that will have a default day of 20.
|
211
|
-
# date_select("credit_card", "bill_due", :
|
245
|
+
# date_select("credit_card", "bill_due", default: { day: 20 })
|
212
246
|
#
|
213
247
|
# # Generates a date select with custom prompts.
|
214
|
-
# date_select("article", "written_on", :
|
248
|
+
# date_select("article", "written_on", prompt: { day: 'Select day', month: 'Select month', year: 'Select year' })
|
215
249
|
#
|
216
250
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
217
251
|
#
|
218
252
|
# 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
|
219
253
|
# all month choices are valid.
|
220
254
|
def date_select(object_name, method, options = {}, html_options = {})
|
221
|
-
|
255
|
+
Tags::DateSelect.new(object_name, method, self, options, html_options).render
|
222
256
|
end
|
223
257
|
|
224
258
|
# Returns a set of select tags (one for hour, minute and optionally second) pre-selected for accessing a
|
@@ -232,31 +266,30 @@ module ActionView
|
|
232
266
|
#
|
233
267
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
234
268
|
#
|
235
|
-
# ==== Examples
|
236
269
|
# # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
|
237
270
|
# time_select("article", "sunrise")
|
238
271
|
#
|
239
272
|
# # Creates a time select tag with a seconds field that, when POSTed, will be stored in the article variables in
|
240
273
|
# # the sunrise attribute.
|
241
|
-
# time_select("article", "start_time", :
|
274
|
+
# time_select("article", "start_time", include_seconds: true)
|
242
275
|
#
|
243
276
|
# # You can set the <tt>:minute_step</tt> to 15 which will give you: 00, 15, 30 and 45.
|
244
|
-
# time_select 'game', 'game_time', {:
|
277
|
+
# time_select 'game', 'game_time', {minute_step: 15}
|
245
278
|
#
|
246
|
-
# # Creates a time select tag with a custom prompt. Use <tt
|
247
|
-
# time_select("article", "written_on", :
|
248
|
-
# time_select("article", "written_on", :
|
249
|
-
# time_select("article", "written_on", :
|
279
|
+
# # Creates a time select tag with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
|
280
|
+
# time_select("article", "written_on", prompt: {hour: 'Choose hour', minute: 'Choose minute', second: 'Choose seconds'})
|
281
|
+
# time_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
|
282
|
+
# time_select("article", "written_on", prompt: true) # generic prompts for all
|
250
283
|
#
|
251
284
|
# # You can set :ampm option to true which will show the hours as: 12 PM, 01 AM .. 11 PM.
|
252
|
-
# time_select 'game', 'game_time', {:
|
285
|
+
# time_select 'game', 'game_time', {ampm: true}
|
253
286
|
#
|
254
287
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
255
288
|
#
|
256
289
|
# 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
|
257
290
|
# all month choices are valid.
|
258
291
|
def time_select(object_name, method, options = {}, html_options = {})
|
259
|
-
|
292
|
+
Tags::TimeSelect.new(object_name, method, self, options, html_options).render
|
260
293
|
end
|
261
294
|
|
262
295
|
# Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a
|
@@ -265,34 +298,33 @@ module ActionView
|
|
265
298
|
#
|
266
299
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
267
300
|
#
|
268
|
-
# ==== Examples
|
269
301
|
# # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
|
270
302
|
# # attribute.
|
271
303
|
# datetime_select("article", "written_on")
|
272
304
|
#
|
273
305
|
# # Generates a datetime select with a year select that starts at 1995 that, when POSTed, will be stored in the
|
274
306
|
# # article variable in the written_on attribute.
|
275
|
-
# datetime_select("article", "written_on", :
|
307
|
+
# datetime_select("article", "written_on", start_year: 1995)
|
276
308
|
#
|
277
309
|
# # Generates a datetime select with a default value of 3 days from the current time that, when POSTed, will
|
278
310
|
# # be stored in the trip variable in the departing attribute.
|
279
|
-
# datetime_select("trip", "departing", :
|
311
|
+
# datetime_select("trip", "departing", default: 3.days.from_now)
|
280
312
|
#
|
281
313
|
# # Generate a datetime select with hours in the AM/PM format
|
282
|
-
# datetime_select("article", "written_on", :
|
314
|
+
# datetime_select("article", "written_on", ampm: true)
|
283
315
|
#
|
284
316
|
# # Generates a datetime select that discards the type that, when POSTed, will be stored in the article variable
|
285
317
|
# # as the written_on attribute.
|
286
|
-
# datetime_select("article", "written_on", :
|
318
|
+
# datetime_select("article", "written_on", discard_type: true)
|
287
319
|
#
|
288
|
-
# # Generates a datetime select with a custom prompt. Use <tt
|
289
|
-
# datetime_select("article", "written_on", :
|
290
|
-
# datetime_select("article", "written_on", :
|
291
|
-
# datetime_select("article", "written_on", :
|
320
|
+
# # Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
|
321
|
+
# datetime_select("article", "written_on", prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
|
322
|
+
# datetime_select("article", "written_on", prompt: {hour: true}) # generic prompt for hours
|
323
|
+
# datetime_select("article", "written_on", prompt: true) # generic prompts for all
|
292
324
|
#
|
293
325
|
# The selects are prepared for multi-parameter assignment to an Active Record object.
|
294
326
|
def datetime_select(object_name, method, options = {}, html_options = {})
|
295
|
-
|
327
|
+
Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render
|
296
328
|
end
|
297
329
|
|
298
330
|
# Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the
|
@@ -304,7 +336,6 @@ module ActionView
|
|
304
336
|
#
|
305
337
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
306
338
|
#
|
307
|
-
# ==== Examples
|
308
339
|
# my_date_time = Time.now + 4.days
|
309
340
|
#
|
310
341
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today).
|
@@ -315,33 +346,32 @@ module ActionView
|
|
315
346
|
#
|
316
347
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
317
348
|
# # with the fields ordered year, month, day rather than month, day, year.
|
318
|
-
# select_datetime(my_date_time, :
|
349
|
+
# select_datetime(my_date_time, order: [:year, :month, :day])
|
319
350
|
#
|
320
351
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
321
352
|
# # with a '/' between each date field.
|
322
|
-
# select_datetime(my_date_time, :
|
353
|
+
# select_datetime(my_date_time, date_separator: '/')
|
323
354
|
#
|
324
355
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
325
356
|
# # with a date fields separated by '/', time fields separated by '' and the date and time fields
|
326
357
|
# # separated by a comma (',').
|
327
|
-
# select_datetime(my_date_time, :
|
358
|
+
# select_datetime(my_date_time, date_separator: '/', time_separator: '', datetime_separator: ',')
|
328
359
|
#
|
329
360
|
# # Generates a datetime select that discards the type of the field and defaults to the datetime in
|
330
361
|
# # my_date_time (four days after today)
|
331
|
-
# select_datetime(my_date_time, :
|
362
|
+
# select_datetime(my_date_time, discard_type: true)
|
332
363
|
#
|
333
364
|
# # Generate a datetime field with hours in the AM/PM format
|
334
|
-
# select_datetime(my_date_time, :
|
365
|
+
# select_datetime(my_date_time, ampm: true)
|
335
366
|
#
|
336
367
|
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today)
|
337
368
|
# # prefixed with 'payday' rather than 'date'
|
338
|
-
# select_datetime(my_date_time, :
|
339
|
-
#
|
340
|
-
# # Generates a datetime select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
341
|
-
# select_datetime(my_date_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
342
|
-
# select_datetime(my_date_time, :prompt => {:hour => true}) # generic prompt for hours
|
343
|
-
# select_datetime(my_date_time, :prompt => true) # generic prompts for all
|
369
|
+
# select_datetime(my_date_time, prefix: 'payday')
|
344
370
|
#
|
371
|
+
# # Generates a datetime select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
|
372
|
+
# select_datetime(my_date_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
|
373
|
+
# select_datetime(my_date_time, prompt: {hour: true}) # generic prompt for hours
|
374
|
+
# select_datetime(my_date_time, prompt: true) # generic prompts for all
|
345
375
|
def select_datetime(datetime = Time.current, options = {}, html_options = {})
|
346
376
|
DateTimeSelector.new(datetime, options, html_options).select_datetime
|
347
377
|
end
|
@@ -353,7 +383,6 @@ module ActionView
|
|
353
383
|
#
|
354
384
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
355
385
|
#
|
356
|
-
# ==== Examples
|
357
386
|
# my_date = Time.now + 6.days
|
358
387
|
#
|
359
388
|
# # Generates a date select that defaults to the date in my_date (six days after today).
|
@@ -364,25 +393,24 @@ module ActionView
|
|
364
393
|
#
|
365
394
|
# # Generates a date select that defaults to the date in my_date (six days after today)
|
366
395
|
# # with the fields ordered year, month, day rather than month, day, year.
|
367
|
-
# select_date(my_date, :
|
396
|
+
# select_date(my_date, order: [:year, :month, :day])
|
368
397
|
#
|
369
398
|
# # Generates a date select that discards the type of the field and defaults to the date in
|
370
399
|
# # my_date (six days after today).
|
371
|
-
# select_date(my_date, :
|
400
|
+
# select_date(my_date, discard_type: true)
|
372
401
|
#
|
373
402
|
# # Generates a date select that defaults to the date in my_date,
|
374
403
|
# # which has fields separated by '/'.
|
375
|
-
# select_date(my_date, :
|
404
|
+
# select_date(my_date, date_separator: '/')
|
376
405
|
#
|
377
406
|
# # Generates a date select that defaults to the datetime in my_date (six days after today)
|
378
407
|
# # prefixed with 'payday' rather than 'date'.
|
379
|
-
# select_date(my_date, :
|
380
|
-
#
|
381
|
-
# # Generates a date select with a custom prompt. Use <tt>:prompt => true</tt> for generic prompts.
|
382
|
-
# select_date(my_date, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
|
383
|
-
# select_date(my_date, :prompt => {:hour => true}) # generic prompt for hours
|
384
|
-
# select_date(my_date, :prompt => true) # generic prompts for all
|
408
|
+
# select_date(my_date, prefix: 'payday')
|
385
409
|
#
|
410
|
+
# # Generates a date select with a custom prompt. Use <tt>prompt: true</tt> for generic prompts.
|
411
|
+
# select_date(my_date, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
|
412
|
+
# select_date(my_date, prompt: {hour: true}) # generic prompt for hours
|
413
|
+
# select_date(my_date, prompt: true) # generic prompts for all
|
386
414
|
def select_date(date = Date.current, options = {}, html_options = {})
|
387
415
|
DateTimeSelector.new(date, options, html_options).select_date
|
388
416
|
end
|
@@ -393,7 +421,6 @@ module ActionView
|
|
393
421
|
#
|
394
422
|
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
|
395
423
|
#
|
396
|
-
# ==== Examples
|
397
424
|
# my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
|
398
425
|
#
|
399
426
|
# # Generates a time select that defaults to the time in my_time.
|
@@ -404,24 +431,26 @@ module ActionView
|
|
404
431
|
#
|
405
432
|
# # Generates a time select that defaults to the time in my_time,
|
406
433
|
# # which has fields separated by ':'.
|
407
|
-
# select_time(my_time, :
|
434
|
+
# select_time(my_time, time_separator: ':')
|
408
435
|
#
|
409
436
|
# # Generates a time select that defaults to the time in my_time,
|
410
437
|
# # that also includes an input for seconds.
|
411
|
-
# select_time(my_time, :
|
438
|
+
# select_time(my_time, include_seconds: true)
|
412
439
|
#
|
413
440
|
# # Generates a time select that defaults to the time in my_time, that has fields
|
414
441
|
# # separated by ':' and includes an input for seconds.
|
415
|
-
# select_time(my_time, :
|
442
|
+
# select_time(my_time, time_separator: ':', include_seconds: true)
|
416
443
|
#
|
417
444
|
# # Generate a time select field with hours in the AM/PM format
|
418
|
-
# select_time(my_time, :
|
445
|
+
# select_time(my_time, ampm: true)
|
419
446
|
#
|
420
|
-
# # Generates a time select with
|
421
|
-
# select_time(my_time, :
|
422
|
-
# select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
|
423
|
-
# select_time(my_time, :prompt => true) # generic prompts for all
|
447
|
+
# # Generates a time select field with hours that range from 2 to 14
|
448
|
+
# select_time(my_time, start_hour: 2, end_hour: 14)
|
424
449
|
#
|
450
|
+
# # Generates a time select with a custom prompt. Use <tt>:prompt</tt> to true for generic prompts.
|
451
|
+
# select_time(my_time, prompt: {day: 'Choose day', month: 'Choose month', year: 'Choose year'})
|
452
|
+
# select_time(my_time, prompt: {hour: true}) # generic prompt for hours
|
453
|
+
# select_time(my_time, prompt: true) # generic prompts for all
|
425
454
|
def select_time(datetime = Time.current, options = {}, html_options = {})
|
426
455
|
DateTimeSelector.new(datetime, options, html_options).select_time
|
427
456
|
end
|
@@ -430,7 +459,6 @@ module ActionView
|
|
430
459
|
# The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
|
431
460
|
# Override the field name using the <tt>:field_name</tt> option, 'second' by default.
|
432
461
|
#
|
433
|
-
# ==== Examples
|
434
462
|
# my_time = Time.now + 16.minutes
|
435
463
|
#
|
436
464
|
# # Generates a select field for seconds that defaults to the seconds for the time in my_time.
|
@@ -441,12 +469,11 @@ module ActionView
|
|
441
469
|
#
|
442
470
|
# # Generates a select field for seconds that defaults to the seconds for the time in my_time
|
443
471
|
# # that is named 'interval' rather than 'second'.
|
444
|
-
# select_second(my_time, :
|
472
|
+
# select_second(my_time, field_name: 'interval')
|
445
473
|
#
|
446
|
-
# # Generates a select field for seconds with a custom prompt. Use <tt
|
474
|
+
# # Generates a select field for seconds with a custom prompt. Use <tt>prompt: true</tt> for a
|
447
475
|
# # generic prompt.
|
448
|
-
# select_second(14, :
|
449
|
-
#
|
476
|
+
# select_second(14, prompt: 'Choose seconds')
|
450
477
|
def select_second(datetime, options = {}, html_options = {})
|
451
478
|
DateTimeSelector.new(datetime, options, html_options).select_second
|
452
479
|
end
|
@@ -456,7 +483,6 @@ module ActionView
|
|
456
483
|
# selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
|
457
484
|
# Override the field name using the <tt>:field_name</tt> option, 'minute' by default.
|
458
485
|
#
|
459
|
-
# ==== Examples
|
460
486
|
# my_time = Time.now + 6.hours
|
461
487
|
#
|
462
488
|
# # Generates a select field for minutes that defaults to the minutes for the time in my_time.
|
@@ -467,12 +493,11 @@ module ActionView
|
|
467
493
|
#
|
468
494
|
# # Generates a select field for minutes that defaults to the minutes for the time in my_time
|
469
495
|
# # that is named 'moment' rather than 'minute'.
|
470
|
-
# select_minute(my_time, :
|
496
|
+
# select_minute(my_time, field_name: 'moment')
|
471
497
|
#
|
472
|
-
# # Generates a select field for minutes with a custom prompt. Use <tt
|
498
|
+
# # Generates a select field for minutes with a custom prompt. Use <tt>prompt: true</tt> for a
|
473
499
|
# # generic prompt.
|
474
|
-
# select_minute(14, :
|
475
|
-
#
|
500
|
+
# select_minute(14, prompt: 'Choose minutes')
|
476
501
|
def select_minute(datetime, options = {}, html_options = {})
|
477
502
|
DateTimeSelector.new(datetime, options, html_options).select_minute
|
478
503
|
end
|
@@ -481,7 +506,6 @@ module ActionView
|
|
481
506
|
# The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
|
482
507
|
# Override the field name using the <tt>:field_name</tt> option, 'hour' by default.
|
483
508
|
#
|
484
|
-
# ==== Examples
|
485
509
|
# my_time = Time.now + 6.hours
|
486
510
|
#
|
487
511
|
# # Generates a select field for hours that defaults to the hour for the time in my_time.
|
@@ -492,24 +516,26 @@ module ActionView
|
|
492
516
|
#
|
493
517
|
# # Generates a select field for hours that defaults to the hour for the time in my_time
|
494
518
|
# # that is named 'stride' rather than 'hour'.
|
495
|
-
# select_hour(my_time, :
|
519
|
+
# select_hour(my_time, field_name: 'stride')
|
496
520
|
#
|
497
|
-
# # Generates a select field for hours with a custom prompt. Use <tt
|
521
|
+
# # Generates a select field for hours with a custom prompt. Use <tt>prompt: true</tt> for a
|
498
522
|
# # generic prompt.
|
499
|
-
# select_hour(13, :
|
523
|
+
# select_hour(13, prompt: 'Choose hour')
|
500
524
|
#
|
501
525
|
# # Generate a select field for hours in the AM/PM format
|
502
|
-
# select_hour(my_time, :
|
526
|
+
# select_hour(my_time, ampm: true)
|
503
527
|
#
|
528
|
+
# # Generates a select field that includes options for hours from 2 to 14.
|
529
|
+
# select_hour(my_time, start_hour: 2, end_hour: 14)
|
504
530
|
def select_hour(datetime, options = {}, html_options = {})
|
505
531
|
DateTimeSelector.new(datetime, options, html_options).select_hour
|
506
532
|
end
|
507
533
|
|
508
534
|
# Returns a select tag with options for each of the days 1 through 31 with the current day selected.
|
509
535
|
# The <tt>date</tt> can also be substituted for a day number.
|
536
|
+
# If you want to display days with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
|
510
537
|
# Override the field name using the <tt>:field_name</tt> option, 'day' by default.
|
511
538
|
#
|
512
|
-
# ==== Examples
|
513
539
|
# my_date = Time.now + 2.days
|
514
540
|
#
|
515
541
|
# # Generates a select field for days that defaults to the day for the date in my_date.
|
@@ -518,14 +544,16 @@ module ActionView
|
|
518
544
|
# # Generates a select field for days that defaults to the number given.
|
519
545
|
# select_day(5)
|
520
546
|
#
|
547
|
+
# # Generates a select field for days that defaults to the number given, but displays it with two digits.
|
548
|
+
# select_day(5, use_two_digit_numbers: true)
|
549
|
+
#
|
521
550
|
# # Generates a select field for days that defaults to the day for the date in my_date
|
522
551
|
# # that is named 'due' rather than 'day'.
|
523
|
-
# select_day(my_time, :
|
552
|
+
# select_day(my_time, field_name: 'due')
|
524
553
|
#
|
525
|
-
# # Generates a select field for days with a custom prompt. Use <tt
|
554
|
+
# # Generates a select field for days with a custom prompt. Use <tt>prompt: true</tt> for a
|
526
555
|
# # generic prompt.
|
527
|
-
# select_day(5, :
|
528
|
-
#
|
556
|
+
# select_day(5, prompt: 'Choose day')
|
529
557
|
def select_day(date, options = {}, html_options = {})
|
530
558
|
DateTimeSelector.new(date, options, html_options).select_day
|
531
559
|
end
|
@@ -537,37 +565,40 @@ module ActionView
|
|
537
565
|
# want both numbers and names, set the <tt>:add_month_numbers</tt> key in +options+ to true. If you would prefer
|
538
566
|
# to show month names as abbreviations, set the <tt>:use_short_month</tt> key in +options+ to true. If you want
|
539
567
|
# to use your own month names, set the <tt>:use_month_names</tt> key in +options+ to an array of 12 month names.
|
568
|
+
# If you want to display months with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
|
540
569
|
# Override the field name using the <tt>:field_name</tt> option, 'month' by default.
|
541
570
|
#
|
542
|
-
# ==== Examples
|
543
571
|
# # Generates a select field for months that defaults to the current month that
|
544
572
|
# # will use keys like "January", "March".
|
545
573
|
# select_month(Date.today)
|
546
574
|
#
|
547
575
|
# # Generates a select field for months that defaults to the current month that
|
548
576
|
# # is named "start" rather than "month".
|
549
|
-
# select_month(Date.today, :
|
577
|
+
# select_month(Date.today, field_name: 'start')
|
550
578
|
#
|
551
579
|
# # Generates a select field for months that defaults to the current month that
|
552
580
|
# # will use keys like "1", "3".
|
553
|
-
# select_month(Date.today, :
|
581
|
+
# select_month(Date.today, use_month_numbers: true)
|
554
582
|
#
|
555
583
|
# # Generates a select field for months that defaults to the current month that
|
556
584
|
# # will use keys like "1 - January", "3 - March".
|
557
|
-
# select_month(Date.today, :
|
585
|
+
# select_month(Date.today, add_month_numbers: true)
|
558
586
|
#
|
559
587
|
# # Generates a select field for months that defaults to the current month that
|
560
588
|
# # will use keys like "Jan", "Mar".
|
561
|
-
# select_month(Date.today, :
|
589
|
+
# select_month(Date.today, use_short_month: true)
|
562
590
|
#
|
563
591
|
# # Generates a select field for months that defaults to the current month that
|
564
592
|
# # will use keys like "Januar", "Marts."
|
565
|
-
# select_month(Date.today, :
|
593
|
+
# select_month(Date.today, use_month_names: %w(Januar Februar Marts ...))
|
566
594
|
#
|
567
|
-
# # Generates a select field for months
|
568
|
-
# #
|
569
|
-
# select_month(
|
595
|
+
# # Generates a select field for months that defaults to the current month that
|
596
|
+
# # will use keys with two digit numbers like "01", "03".
|
597
|
+
# select_month(Date.today, use_two_digit_numbers: true)
|
570
598
|
#
|
599
|
+
# # Generates a select field for months with a custom prompt. Use <tt>prompt: true</tt> for a
|
600
|
+
# # generic prompt.
|
601
|
+
# select_month(14, prompt: 'Choose month')
|
571
602
|
def select_month(date, options = {}, html_options = {})
|
572
603
|
DateTimeSelector.new(date, options, html_options).select_month
|
573
604
|
end
|
@@ -578,50 +609,53 @@ module ActionView
|
|
578
609
|
# greater than <tt>:end_year</tt>. The <tt>date</tt> can also be substituted for a year given as a number.
|
579
610
|
# Override the field name using the <tt>:field_name</tt> option, 'year' by default.
|
580
611
|
#
|
581
|
-
# ==== Examples
|
582
612
|
# # Generates a select field for years that defaults to the current year that
|
583
613
|
# # has ascending year values.
|
584
|
-
# select_year(Date.today, :
|
614
|
+
# select_year(Date.today, start_year: 1992, end_year: 2007)
|
585
615
|
#
|
586
616
|
# # Generates a select field for years that defaults to the current year that
|
587
617
|
# # is named 'birth' rather than 'year'.
|
588
|
-
# select_year(Date.today, :
|
618
|
+
# select_year(Date.today, field_name: 'birth')
|
589
619
|
#
|
590
620
|
# # Generates a select field for years that defaults to the current year that
|
591
621
|
# # has descending year values.
|
592
|
-
# select_year(Date.today, :
|
622
|
+
# select_year(Date.today, start_year: 2005, end_year: 1900)
|
593
623
|
#
|
594
624
|
# # Generates a select field for years that defaults to the year 2006 that
|
595
625
|
# # has ascending year values.
|
596
|
-
# select_year(2006, :
|
626
|
+
# select_year(2006, start_year: 2000, end_year: 2010)
|
597
627
|
#
|
598
|
-
# # Generates a select field for years with a custom prompt. Use <tt
|
628
|
+
# # Generates a select field for years with a custom prompt. Use <tt>prompt: true</tt> for a
|
599
629
|
# # generic prompt.
|
600
|
-
# select_year(14, :
|
601
|
-
#
|
630
|
+
# select_year(14, prompt: 'Choose year')
|
602
631
|
def select_year(date, options = {}, html_options = {})
|
603
632
|
DateTimeSelector.new(date, options, html_options).select_year
|
604
633
|
end
|
605
634
|
|
606
635
|
# Returns an html time tag for the given date or time.
|
607
636
|
#
|
608
|
-
# ==== Examples
|
609
637
|
# time_tag Date.today # =>
|
610
638
|
# <time datetime="2010-11-04">November 04, 2010</time>
|
611
639
|
# time_tag Time.now # =>
|
612
640
|
# <time datetime="2010-11-04T17:55:45+01:00">November 04, 2010 17:55</time>
|
613
641
|
# time_tag Date.yesterday, 'Yesterday' # =>
|
614
642
|
# <time datetime="2010-11-03">Yesterday</time>
|
615
|
-
# time_tag Date.today, :
|
643
|
+
# time_tag Date.today, pubdate: true # =>
|
616
644
|
# <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time>
|
617
|
-
#
|
618
|
-
|
645
|
+
# time_tag Date.today, datetime: Date.today.strftime('%G-W%V') # =>
|
646
|
+
# <time datetime="2010-W44">November 04, 2010</time>
|
647
|
+
#
|
648
|
+
# <%= time_tag Time.now do %>
|
649
|
+
# <span>Right now</span>
|
650
|
+
# <% end %>
|
651
|
+
# # => <time datetime="2010-11-04T17:55:45+01:00"><span>Right now</span></time>
|
652
|
+
def time_tag(date_or_time, *args, &block)
|
619
653
|
options = args.extract_options!
|
620
654
|
format = options.delete(:format) || :long
|
621
655
|
content = args.first || I18n.l(date_or_time, :format => format)
|
622
|
-
datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.
|
656
|
+
datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601
|
623
657
|
|
624
|
-
content_tag(:time, content, options.reverse_merge(:datetime => datetime))
|
658
|
+
content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block)
|
625
659
|
end
|
626
660
|
end
|
627
661
|
|
@@ -659,11 +693,7 @@ module ActionView
|
|
659
693
|
@options[:discard_minute] ||= true if @options[:discard_hour]
|
660
694
|
@options[:discard_second] ||= true unless @options[:include_seconds] && !@options[:discard_minute]
|
661
695
|
|
662
|
-
|
663
|
-
# valid (otherwise it could be 31 and February wouldn't be a valid date)
|
664
|
-
if @datetime && @options[:discard_day] && !@options[:discard_month]
|
665
|
-
@datetime = @datetime.change(:day => 1)
|
666
|
-
end
|
696
|
+
set_day_if_discarded
|
667
697
|
|
668
698
|
if @options[:tag] && @options[:ignore_date]
|
669
699
|
select_time
|
@@ -686,11 +716,7 @@ module ActionView
|
|
686
716
|
@options[:discard_month] ||= true unless order.include?(:month)
|
687
717
|
@options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day)
|
688
718
|
|
689
|
-
|
690
|
-
# valid (otherwise it could be 31 and February wouldn't be a valid date)
|
691
|
-
if @datetime && @options[:discard_day] && !@options[:discard_month]
|
692
|
-
@datetime = @datetime.change(:day => 1)
|
693
|
-
end
|
719
|
+
set_day_if_discarded
|
694
720
|
|
695
721
|
[:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) }
|
696
722
|
|
@@ -733,7 +759,11 @@ module ActionView
|
|
733
759
|
if @options[:use_hidden] || @options[:discard_hour]
|
734
760
|
build_hidden(:hour, hour)
|
735
761
|
else
|
736
|
-
|
762
|
+
options = {}
|
763
|
+
options[:ampm] = @options[:ampm] || false
|
764
|
+
options[:start] = @options[:start_hour] || 0
|
765
|
+
options[:end] = @options[:end_hour] || 23
|
766
|
+
build_options_and_select(:hour, hour, options)
|
737
767
|
end
|
738
768
|
end
|
739
769
|
|
@@ -792,6 +822,14 @@ module ActionView
|
|
792
822
|
end
|
793
823
|
end
|
794
824
|
|
825
|
+
# If the day is hidden, the day should be set to the 1st so all month and year choices are
|
826
|
+
# valid. Otherwise, February 31st or February 29th, 2011 can be selected, which are invalid.
|
827
|
+
def set_day_if_discarded
|
828
|
+
if @datetime && @options[:discard_day]
|
829
|
+
@datetime = @datetime.change(:day => 1)
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
795
833
|
# Returns translated month names, but also ensures that a custom month
|
796
834
|
# name array has a leading nil element.
|
797
835
|
def month_names
|
@@ -822,6 +860,9 @@ module ActionView
|
|
822
860
|
# If <tt>:use_month_numbers</tt> option is passed
|
823
861
|
# month_name(1) => 1
|
824
862
|
#
|
863
|
+
# If <tt>:use_two_month_numbers</tt> option is passed
|
864
|
+
# month_name(1) => '01'
|
865
|
+
#
|
825
866
|
# If <tt>:add_month_numbers</tt> option is passed
|
826
867
|
# month_name(1) => "1 - January"
|
827
868
|
def month_name(number)
|
@@ -841,7 +882,16 @@ module ActionView
|
|
841
882
|
end
|
842
883
|
|
843
884
|
def translated_date_order
|
844
|
-
I18n.translate(:'date.order', :locale => @options[:locale]
|
885
|
+
date_order = I18n.translate(:'date.order', :locale => @options[:locale], :default => [])
|
886
|
+
date_order = date_order.map { |element| element.to_sym }
|
887
|
+
|
888
|
+
forbidden_elements = date_order - [:year, :month, :day]
|
889
|
+
if forbidden_elements.any?
|
890
|
+
raise StandardError,
|
891
|
+
"#{@options[:locale]}.date.order only accepts :year, :month and :day"
|
892
|
+
end
|
893
|
+
|
894
|
+
date_order
|
845
895
|
end
|
846
896
|
|
847
897
|
# Build full select tag from date type and options.
|
@@ -850,21 +900,30 @@ module ActionView
|
|
850
900
|
end
|
851
901
|
|
852
902
|
# Build select option html from date value and options.
|
853
|
-
# build_options(15, :
|
903
|
+
# build_options(15, start: 1, end: 31)
|
854
904
|
# => "<option value="1">1</option>
|
855
905
|
# <option value="2">2</option>
|
856
906
|
# <option value="3">3</option>..."
|
857
907
|
#
|
908
|
+
# If <tt>use_two_digit_numbers: true</tt> option is passed
|
909
|
+
# build_options(15, start: 1, end: 31, use_two_digit_numbers: true)
|
910
|
+
# => "<option value="1">01</option>
|
911
|
+
# <option value="2">02</option>
|
912
|
+
# <option value="3">03</option>..."
|
913
|
+
#
|
858
914
|
# If <tt>:step</tt> options is passed
|
859
|
-
# build_options(15, :
|
915
|
+
# build_options(15, start: 1, end: 31, step: 2)
|
860
916
|
# => "<option value="1">1</option>
|
861
917
|
# <option value="3">3</option>
|
862
918
|
# <option value="5">5</option>..."
|
863
919
|
def build_options(selected, options = {})
|
920
|
+
options = {
|
921
|
+
leading_zeros: true, ampm: false, use_two_digit_numbers: false
|
922
|
+
}.merge!(options)
|
923
|
+
|
864
924
|
start = options.delete(:start) || 0
|
865
925
|
stop = options.delete(:end) || 59
|
866
926
|
step = options.delete(:step) || 1
|
867
|
-
options.reverse_merge!({:leading_zeros => true, :ampm => false, :use_two_digit_numbers => false})
|
868
927
|
leading_zeros = options.delete(:leading_zeros)
|
869
928
|
|
870
929
|
select_options = []
|
@@ -876,6 +935,7 @@ module ActionView
|
|
876
935
|
text = options[:ampm] ? AMPM_TRANSLATION[i] : text
|
877
936
|
select_options << content_tag(:option, text, tag_options)
|
878
937
|
end
|
938
|
+
|
879
939
|
(select_options.join("\n") + "\n").html_safe
|
880
940
|
end
|
881
941
|
|
@@ -888,8 +948,9 @@ module ActionView
|
|
888
948
|
select_options = {
|
889
949
|
:id => input_id_from_type(type),
|
890
950
|
:name => input_name_from_type(type)
|
891
|
-
}.merge(@html_options)
|
892
|
-
select_options
|
951
|
+
}.merge!(@html_options)
|
952
|
+
select_options[:disabled] = 'disabled' if @options[:disabled]
|
953
|
+
select_options[:class] = type if @options[:with_css_classes]
|
893
954
|
|
894
955
|
select_html = "\n"
|
895
956
|
select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank]
|
@@ -900,7 +961,7 @@ module ActionView
|
|
900
961
|
end
|
901
962
|
|
902
963
|
# Builds a prompt option tag with supplied options or from default options.
|
903
|
-
# prompt_option_tag(:month, :
|
964
|
+
# prompt_option_tag(:month, prompt: 'Select month')
|
904
965
|
# => "<option value="">Select month</option>"
|
905
966
|
def prompt_option_tag(type, options)
|
906
967
|
prompt = case options
|
@@ -925,8 +986,8 @@ module ActionView
|
|
925
986
|
:id => input_id_from_type(type),
|
926
987
|
:name => input_name_from_type(type),
|
927
988
|
:value => value
|
928
|
-
}.merge(@html_options.slice(:disabled))
|
929
|
-
select_options
|
989
|
+
}.merge!(@html_options.slice(:disabled))
|
990
|
+
select_options[:disabled] = 'disabled' if @options[:disabled]
|
930
991
|
|
931
992
|
tag(:input, select_options) + "\n".html_safe
|
932
993
|
end
|
@@ -968,92 +1029,52 @@ module ActionView
|
|
968
1029
|
|
969
1030
|
# Returns the separator for a given datetime component.
|
970
1031
|
def separator(type)
|
1032
|
+
return "" if @options[:use_hidden]
|
1033
|
+
|
971
1034
|
case type
|
972
|
-
when :year
|
973
|
-
@options[:
|
974
|
-
when :month
|
975
|
-
@options[:discard_month] ? "" : @options[:date_separator]
|
976
|
-
when :day
|
977
|
-
@options[:discard_day] ? "" : @options[:date_separator]
|
1035
|
+
when :year, :month, :day
|
1036
|
+
@options[:"discard_#{type}"] ? "" : @options[:date_separator]
|
978
1037
|
when :hour
|
979
1038
|
(@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator]
|
980
|
-
when :minute
|
981
|
-
@options[:
|
982
|
-
when :second
|
983
|
-
@options[:include_seconds] ? @options[:time_separator] : ""
|
1039
|
+
when :minute, :second
|
1040
|
+
@options[:"discard_#{type}"] ? "" : @options[:time_separator]
|
984
1041
|
end
|
985
1042
|
end
|
986
1043
|
end
|
987
1044
|
|
988
|
-
module DateHelperInstanceTag
|
989
|
-
def to_date_select_tag(options = {}, html_options = {})
|
990
|
-
datetime_selector(options, html_options).select_date.html_safe
|
991
|
-
end
|
992
|
-
|
993
|
-
def to_time_select_tag(options = {}, html_options = {})
|
994
|
-
datetime_selector(options, html_options).select_time.html_safe
|
995
|
-
end
|
996
|
-
|
997
|
-
def to_datetime_select_tag(options = {}, html_options = {})
|
998
|
-
datetime_selector(options, html_options).select_datetime.html_safe
|
999
|
-
end
|
1000
|
-
|
1001
|
-
private
|
1002
|
-
def datetime_selector(options, html_options)
|
1003
|
-
datetime = value(object) || default_datetime(options)
|
1004
|
-
@auto_index ||= nil
|
1005
|
-
|
1006
|
-
options = options.dup
|
1007
|
-
options[:field_name] = @method_name
|
1008
|
-
options[:include_position] = true
|
1009
|
-
options[:prefix] ||= @object_name
|
1010
|
-
options[:index] = @auto_index if @auto_index && !options.has_key?(:index)
|
1011
|
-
|
1012
|
-
DateTimeSelector.new(datetime, options, html_options)
|
1013
|
-
end
|
1014
|
-
|
1015
|
-
def default_datetime(options)
|
1016
|
-
return if options[:include_blank] || options[:prompt]
|
1017
|
-
|
1018
|
-
case options[:default]
|
1019
|
-
when nil
|
1020
|
-
Time.current
|
1021
|
-
when Date, Time
|
1022
|
-
options[:default]
|
1023
|
-
else
|
1024
|
-
default = options[:default].dup
|
1025
|
-
|
1026
|
-
# Rename :minute and :second to :min and :sec
|
1027
|
-
default[:min] ||= default[:minute]
|
1028
|
-
default[:sec] ||= default[:second]
|
1029
|
-
|
1030
|
-
time = Time.current
|
1031
|
-
|
1032
|
-
[:year, :month, :day, :hour, :min, :sec].each do |key|
|
1033
|
-
default[key] ||= time.send(key)
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
Time.utc_time(
|
1037
|
-
default[:year], default[:month], default[:day],
|
1038
|
-
default[:hour], default[:min], default[:sec]
|
1039
|
-
)
|
1040
|
-
end
|
1041
|
-
end
|
1042
|
-
end
|
1043
|
-
|
1044
|
-
class InstanceTag #:nodoc:
|
1045
|
-
include DateHelperInstanceTag
|
1046
|
-
end
|
1047
|
-
|
1048
1045
|
class FormBuilder
|
1046
|
+
# Wraps ActionView::Helpers::DateHelper#date_select for form builders:
|
1047
|
+
#
|
1048
|
+
# <%= form_for @person do |f| %>
|
1049
|
+
# <%= f.date_select :birth_date %>
|
1050
|
+
# <%= f.submit %>
|
1051
|
+
# <% end %>
|
1052
|
+
#
|
1053
|
+
# Please refer to the documentation of the base helper for details.
|
1049
1054
|
def date_select(method, options = {}, html_options = {})
|
1050
1055
|
@template.date_select(@object_name, method, objectify_options(options), html_options)
|
1051
1056
|
end
|
1052
1057
|
|
1058
|
+
# Wraps ActionView::Helpers::DateHelper#time_select for form builders:
|
1059
|
+
#
|
1060
|
+
# <%= form_for @race do |f| %>
|
1061
|
+
# <%= f.time_select :average_lap %>
|
1062
|
+
# <%= f.submit %>
|
1063
|
+
# <% end %>
|
1064
|
+
#
|
1065
|
+
# Please refer to the documentation of the base helper for details.
|
1053
1066
|
def time_select(method, options = {}, html_options = {})
|
1054
1067
|
@template.time_select(@object_name, method, objectify_options(options), html_options)
|
1055
1068
|
end
|
1056
1069
|
|
1070
|
+
# Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
|
1071
|
+
#
|
1072
|
+
# <%= form_for @person do |f| %>
|
1073
|
+
# <%= f.time_select :last_request_at %>
|
1074
|
+
# <%= f.submit %>
|
1075
|
+
# <% end %>
|
1076
|
+
#
|
1077
|
+
# Please refer to the documentation of the base helper for details.
|
1057
1078
|
def datetime_select(method, options = {}, html_options = {})
|
1058
1079
|
@template.datetime_select(@object_name, method, objectify_options(options), html_options)
|
1059
1080
|
end
|