Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTML5 input[type="time"] helper #5715

Merged
merged 1 commit into from May 18, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions 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
Expand Down
17 changes: 17 additions & 0 deletions actionpack/lib/action_view/helpers/form_helper.rb
Expand Up @@ -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")
# # => <input id="task_started_at" name="task[started_at]" type="time" />
#
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")
Expand Down
11 changes: 11 additions & 0 deletions actionpack/lib/action_view/helpers/form_tag_helper.rb
Expand Up @@ -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
# * <tt>:min</tt> - The minimum acceptable value.
# * <tt>:max</tt> - The maximum acceptable value.
# * <tt>:step</tt> - 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
Expand Down
1 change: 1 addition & 0 deletions actionpack/lib/action_view/helpers/tags.rb
Expand Up @@ -25,6 +25,7 @@ module Tags #:nodoc:
autoload :TelField
autoload :TextArea
autoload :TextField
autoload :TimeField
autoload :TimeSelect
autoload :TimeZoneSelect
autoload :UrlField
Expand Down
14 changes: 14 additions & 0 deletions 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") }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeremy I've just added fractional seconds to time.

@options = options
super
end
end
end
end
end
26 changes: 26 additions & 0 deletions actionpack/test/template/form_helper_test.rb
Expand Up @@ -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 = %{<input id="post_written_on" name="post[written_on]" type="time" value="00:00:00.000" />}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the value required? I think that if we don't have a value it should be blank.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafaelfranca you are right, the value isn't required.
Time is not blank in this case, it is 00:00:00.000.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Thank you.

assert_dom_equal(expected, time_field("post", "written_on"))
end

def test_time_field_with_datetime_value
expected = %{<input id="post_written_on" name="post[written_on]" type="time" value="01:02:03.000" />}
@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 = %{<input id="post_written_on" name="post[written_on]" type="time" value="01:02:03.000" />}
@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 = %{<input id="post_written_on" name="post[written_on]" type="time" />}
@post.written_on = nil
assert_dom_equal(expected, time_field("post", "written_on"))
end

def test_url_field
expected = %{<input id="user_homepage" name="user[homepage]" type="url" />}
assert_dom_equal(expected, url_field("user", "homepage"))
Expand Down
5 changes: 5 additions & 0 deletions actionpack/test/template/form_tag_helper_test.rb
Expand Up @@ -459,6 +459,11 @@ def test_date_field_tag
assert_dom_equal(expected, date_field_tag("cell"))
end

def test_time_field_tag
expected = %{<input id="cell" name="cell" type="time" />}
assert_dom_equal(expected, time_field_tag("cell"))
end

def test_url_field_tag
expected = %{<input id="homepage" name="homepage" type="url" />}
assert_dom_equal(expected, url_field_tag("homepage"))
Expand Down
8 changes: 5 additions & 3 deletions guides/source/form_helpers.textile
Expand Up @@ -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:

<erb>
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
Expand All @@ -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) %>
</erb>

Output:
Expand All @@ -174,11 +175,12 @@ Output:
<input id="user_born_on" name="user[born_on]" type="date" />
<input id="user_homepage" name="user[homepage]" type="url" />
<input id="user_address" name="user[address]" type="email" />
<input id="task_started_at" name="task[started_at]" type="time" />
</html>

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.

Expand Down Expand Up @@ -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.
Expand Down