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: + Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript. -IMPORTANT: The search, telephone, date, URL, and email inputs are HTML5 controls. If you require your app to have a consistent experience in older browsers, you will need an HTML5 polyfill (provided by CSS and/or JavaScript). There is definitely "no shortage of solutions for this":https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills, although a couple of popular tools at the moment are "Modernizr":http://www.modernizr.com/ and "yepnope":http://yepnopejs.com/, which provide a simple way to add functionality based on the presence of detected HTML5 features. +IMPORTANT: The search, telephone, date, time, URL, and email inputs are HTML5 controls. If you require your app to have a consistent experience in older browsers, you will need an HTML5 polyfill (provided by CSS and/or JavaScript). There is definitely "no shortage of solutions for this":https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills, although a couple of popular tools at the moment are "Modernizr":http://www.modernizr.com/ and "yepnope":http://yepnopejs.com/, which provide a simple way to add functionality based on the presence of detected HTML5 features. TIP: If you're using password input fields (for any purpose), you might want to configure your application to prevent those parameters from being logged. You can learn about this in the "Security Guide":security.html#logging. @@ -471,7 +473,7 @@ Rails _used_ to have a +country_select+ helper for choosing countries, but this h3. Using Date and Time Form Helpers -You can choose not to use the form helpers generating HTML5 date input fields and use the alternative date and time helpers. These date and time helpers differ from all the other form helpers in two important respects: +You can choose not to use the form helpers generating HTML5 date and time input fields and use the alternative date and time helpers. These date and time helpers differ from all the other form helpers in two important respects: # Dates and times are not representable by a single input element. Instead you have several, one for each component (year, month, day etc.) and so there is no single value in your +params+ hash with your date or time. # Other helpers use the +_tag+ suffix to indicate whether a helper is a barebones helper or one that operates on model objects. With dates and times, +select_date+, +select_time+ and +select_datetime+ are the barebones helpers, +date_select+, +time_select+ and +datetime_select+ are the equivalent model object helpers.