diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index df249958e9..23db1b50f5 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,17 @@ +* Add `include_seconds` option for `time_field` + + <%= form.time_field :foo, include_seconds: false %> + # => + + Default includes seconds: + + <%= form.time_field :foo %> + # => + + This allows you to take advantage of [different rendering options](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time#time_value_format) in some browsers. + + *Alex Ghiculescu* + * The `translate` helper now passes `default` values that aren't translation keys through `I18n.translate` for interpolation. @@ -49,12 +63,12 @@ the first argument or as a block. <%= button_to "Delete", post_path(@post), method: :delete %> - <%# =>
+ # =>
<%= button_to post_path(@post), method: :delete do %> Delete <% end %> - <%# =>
+ # =>
*Sean Doyle*, *Dusan Orlovic* diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index 3c4fdeade2..dbdc864b43 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -1402,8 +1402,9 @@ module ActionView # Returns a text_field of type "time". # # The default value is generated by trying to call +strftime+ with "%T.%L" - # on the object's value. It is still possible to override that - # by passing the "value" option. + # on the object's value. If you pass "include_seconds: false", it will be + # formatted by trying to call +strftime+ with "%H:%M" on the object's value. + # It is also possible to override this by passing the "value" option. # # === Options # * Accepts same options as time_field_tag @@ -1424,6 +1425,12 @@ module ActionView # time_field("task", "started_at", min: "01:00:00") # # => # + # By default, provided times will be formatted including seconds. You can render just the hour + # and minute by passing `include_seconds: false`. Some browsers will render a simpler UI + # if you exclude seconds in the timestamp format. + # + # time_field("task", "started_at", value: Time.now, include_seconds: false) + # # => def time_field(object_name, method, options = {}) Tags::TimeField.new(object_name, method, self, options).render end diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb index a4b91671cd..f0a9c14f12 100644 --- a/actionview/lib/action_view/helpers/form_tag_helper.rb +++ b/actionview/lib/action_view/helpers/form_tag_helper.rb @@ -713,6 +713,7 @@ module ActionView # * :min - The minimum acceptable value. # * :max - The maximum acceptable value. # * :step - The acceptable value granularity. + # * :include_seconds - Include seconds and ms in the output timestamp format (true by default). # * Otherwise accepts the same options as text_field_tag. def time_field_tag(name, value = nil, options = {}) text_field_tag(name, value, options.merge(type: :time)) diff --git a/actionview/lib/action_view/helpers/tags/time_field.rb b/actionview/lib/action_view/helpers/tags/time_field.rb index e5e0b84891..ebd49e4621 100644 --- a/actionview/lib/action_view/helpers/tags/time_field.rb +++ b/actionview/lib/action_view/helpers/tags/time_field.rb @@ -4,9 +4,18 @@ module ActionView module Helpers module Tags # :nodoc: class TimeField < DatetimeField # :nodoc: + def initialize(object_name, method_name, template_object, options = {}) + @include_seconds = options.delete(:include_seconds) { true } + super + end + private def format_date(value) - value&.strftime("%T.%L") + if @include_seconds + value&.strftime("%T.%L") + else + value&.strftime("%H:%M") + end end end end diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index b28f49412c..2dec4c61eb 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -1156,6 +1156,14 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal(expected, time_field("post", "written_on", min: min_value, max: max_value)) end + def test_time_field_without_seconds + expected = %{} + @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3) + min_value = DateTime.new(2000, 6, 15, 20, 45, 30) + max_value = DateTime.new(2010, 8, 15, 10, 25, 00) + assert_dom_equal(expected, time_field("post", "written_on", include_seconds: false, min: min_value, max: max_value)) + end + def test_datetime_field expected = %{} assert_dom_equal(expected, datetime_field("post", "written_on"))