diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 3f2593710e3af080d9dbd2ffc2d10c53c362bc96..41af29573e034649ba249d22c8278f50981c2f6d 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,5 +1,7 @@
## Rails 4.0.0 (unreleased) ##
+* Add `time_field` and `time_field_tag` helpers which render an `input[type="time"]` tag. *Alex Soulim*
+
* Removed old text_helper apis for highlight, excerpt and word_wrap *Jeremy Walker*
* Templates without a handler extension now raises a deprecation warning but still
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index cc1f13319604a2a30cf12da1e42ca56f6d66db46..6510610034424f3f8db79f6b5e8404c5363b65e4 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -990,6 +990,23 @@ def date_field(object_name, method, options = {})
Tags::DateField.new(object_name, method, self, options).render
end
+ # Returns a text_field of type "time".
+ #
+ # The default value is generated by trying to call +strftime+ with "%T.%L"
+ # on the objects's value. It is still possible to override that
+ # by passing the "value" option.
+ #
+ # === Options
+ # * Accepts same options as time_field_tag
+ #
+ # === Example
+ # time_field("task", "started_at")
+ # # =>
+ #
+ def time_field(object_name, method, options = {})
+ Tags::TimeField.new(object_name, method, self, options).render
+ end
+
# Returns a text_field of type "url".
#
# url_field("user", "homepage")
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 9e5c66f4a97726e24ebd1077e6805a45ecc5785a..e65b4e3e9586c78874dc836b10eadc4b4f47937d 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -549,6 +549,17 @@ def date_field_tag(name, value = nil, options = {})
text_field_tag(name, value, options.stringify_keys.update("type" => "date"))
end
+ # Creates a text field of type "time".
+ #
+ # === Options
+ # * :min - The minimum acceptable value.
+ # * :max - The maximum acceptable value.
+ # * :step - The acceptable value granularity.
+ # * Otherwise accepts the same options as text_field_tag.
+ def time_field_tag(name, value = nil, options = {})
+ text_field_tag(name, value, options.stringify_keys.update("type" => "time"))
+ end
+
# Creates a text field of type "url".
#
# ==== Options
diff --git a/actionpack/lib/action_view/helpers/tags.rb b/actionpack/lib/action_view/helpers/tags.rb
index 3cf762877febe15bd92d04630ac3dbcde93ae52c..5cd77c8ec34a0351962e3a228286e54191e7cc73 100644
--- a/actionpack/lib/action_view/helpers/tags.rb
+++ b/actionpack/lib/action_view/helpers/tags.rb
@@ -25,6 +25,7 @@ module Tags #:nodoc:
autoload :TelField
autoload :TextArea
autoload :TextField
+ autoload :TimeField
autoload :TimeSelect
autoload :TimeZoneSelect
autoload :UrlField
diff --git a/actionpack/lib/action_view/helpers/tags/time_field.rb b/actionpack/lib/action_view/helpers/tags/time_field.rb
new file mode 100644
index 0000000000000000000000000000000000000000..271dc00c54810d0f1ebb218d6c80d04a5aaf4ae9
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/tags/time_field.rb
@@ -0,0 +1,14 @@
+module ActionView
+ module Helpers
+ module Tags
+ class TimeField < TextField #:nodoc:
+ def render
+ options = @options.stringify_keys
+ options["value"] = @options.fetch("value") { value(object).try(:strftime, "%T.%L") }
+ @options = options
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index beb3ea752aeb5be8249030c2bc82eaa56d2ec5b1..27cc3ad48a05554f7af688825ea43899c5a1871a 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -646,6 +646,32 @@ def test_date_field_with_nil_value
assert_dom_equal(expected, date_field("post", "written_on"))
end
+ def test_time_field
+ expected = %{}
+ assert_dom_equal(expected, time_field("post", "written_on"))
+ end
+
+ def test_time_field_with_datetime_value
+ expected = %{}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ assert_dom_equal(expected, time_field("post", "written_on"))
+ end
+
+ def test_time_field_with_timewithzone_value
+ previous_time_zone, Time.zone = Time.zone, 'UTC'
+ expected = %{}
+ @post.written_on = Time.zone.parse('2004-06-15 01:02:03')
+ assert_dom_equal(expected, time_field("post", "written_on"))
+ ensure
+ Time.zone = previous_time_zone
+ end
+
+ def test_time_field_with_nil_value
+ expected = %{}
+ @post.written_on = nil
+ assert_dom_equal(expected, time_field("post", "written_on"))
+ end
+
def test_url_field
expected = %{}
assert_dom_equal(expected, url_field("user", "homepage"))
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index 7a645217b82dc22bd66b037a62ed867544a88603..6574e1355822fa93681871cd61fc8c857fe79f38 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -459,6 +459,11 @@ def test_date_field_tag
assert_dom_equal(expected, date_field_tag("cell"))
end
+ def test_time_field_tag
+ expected = %{}
+ assert_dom_equal(expected, time_field_tag("cell"))
+ end
+
def test_url_field_tag
expected = %{}
assert_dom_equal(expected, url_field_tag("homepage"))
diff --git a/guides/source/form_helpers.textile b/guides/source/form_helpers.textile
index 711ed3d859145012e2b1de0897674b8049e1c85d..033b33ec3b3bda63f6ed60d81d0b150b03a39988 100644
--- a/guides/source/form_helpers.textile
+++ b/guides/source/form_helpers.textile
@@ -150,7 +150,7 @@ NOTE: Always use labels for checkbox and radio buttons. They associate text with
h4. Other Helpers of Interest
-Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, URL fields and email fields:
+Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, time fields, URL fields and email fields:
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
@@ -161,6 +161,7 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel
<%= date_field(:user, :born_on) %>
<%= url_field(:user, :homepage) %>
<%= email_field(:user, :address) %>
+<%= time_field(:task, :started_at) %>
Output:
@@ -174,11 +175,12 @@ Output:
+