mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #6359 from carlosgaldino/add-html5-inputs
Add HTML5 color and date/time inputs
This commit is contained in:
commit
65d2a60a8c
13 changed files with 446 additions and 2 deletions
|
@ -1,5 +1,10 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* Add `week_field`, `week_field_tag`, `month_field`, `month_field_tag`, `datetime_local_field`,
|
||||
`datetime_local_field_tag`, `datetime_field` and `datetime_field_tag` helpers. *Carlos Galdino*
|
||||
|
||||
* Add `color_field` and `color_field_tag` helpers. *Carlos Galdino*
|
||||
|
||||
* `assert_generates`, `assert_recognizes`, and `assert_routing` all raise
|
||||
`Assertion` instead of `RoutingError` *David Chelimsky*
|
||||
|
||||
|
|
|
@ -939,6 +939,15 @@ module ActionView
|
|||
Tags::RadioButton.new(object_name, method, self, tag_value, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "color".
|
||||
#
|
||||
# color_field("car", "color")
|
||||
# # => <input id="car_color" name="car[color]" type="color" value="#000000" />
|
||||
#
|
||||
def color_field(object_name, method, options = {})
|
||||
Tags::ColorField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns an input of type "search" for accessing a specified attribute (identified by +method+) on an object
|
||||
# assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
|
||||
# some browsers.
|
||||
|
@ -1007,6 +1016,74 @@ module ActionView
|
|||
Tags::TimeField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "datetime".
|
||||
#
|
||||
# datetime_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="datetime" />
|
||||
#
|
||||
# The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T.%L%z"
|
||||
# on the object's value, which makes it behave as expected for instances
|
||||
# of DateTime and ActiveSupport::TimeWithZone.
|
||||
#
|
||||
# @user.born_on = Date.new(1984, 1, 12)
|
||||
# datetime_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="datetime" value="1984-01-12T00:00:00.000+0000" />
|
||||
#
|
||||
def datetime_field(object_name, method, options = {})
|
||||
Tags::DatetimeField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "datetime-local".
|
||||
#
|
||||
# datetime_local_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
|
||||
#
|
||||
# The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T"
|
||||
# on the object's value, which makes it behave as expected for instances
|
||||
# of DateTime and ActiveSupport::TimeWithZone.
|
||||
#
|
||||
# @user.born_on = Date.new(1984, 1, 12)
|
||||
# datetime_local_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
|
||||
#
|
||||
def datetime_local_field(object_name, method, options = {})
|
||||
Tags::DatetimeLocalField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "month".
|
||||
#
|
||||
# month_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="month" />
|
||||
#
|
||||
# The default value is generated by trying to call +strftime+ with "%Y-%m"
|
||||
# on the object's value, which makes it behave as expected for instances
|
||||
# of DateTime and ActiveSupport::TimeWithZone.
|
||||
#
|
||||
# @user.born_on = Date.new(1984, 1, 27)
|
||||
# month_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-01" />
|
||||
#
|
||||
def month_field(object_name, method, options = {})
|
||||
Tags::MonthField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "week".
|
||||
#
|
||||
# week_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="week" />
|
||||
#
|
||||
# The default value is generated by trying to call +strftime+ with "%Y-W%W"
|
||||
# on the object's value, which makes it behave as expected for instances
|
||||
# of DateTime and ActiveSupport::TimeWithZone.
|
||||
#
|
||||
# @user.born_on = Date.new(1984, 5, 12)
|
||||
# week_field("user", "born_on")
|
||||
# # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-W19" />
|
||||
#
|
||||
def week_field(object_name, method, options = {})
|
||||
Tags::WeekField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
||||
# Returns a text_field of type "url".
|
||||
#
|
||||
# url_field("user", "homepage")
|
||||
|
|
|
@ -524,6 +524,14 @@ module ActionView
|
|||
output.safe_concat("</fieldset>")
|
||||
end
|
||||
|
||||
# Creates a text field of type "color".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as text_field_tag.
|
||||
def color_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "color"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "search".
|
||||
#
|
||||
# ==== Options
|
||||
|
@ -560,6 +568,50 @@ module ActionView
|
|||
text_field_tag(name, value, options.stringify_keys.update("type" => "time"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "datetime".
|
||||
#
|
||||
# === 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 datetime_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "datetime"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "datetime-local".
|
||||
#
|
||||
# === 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 datetime_local_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "datetime-local"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "month".
|
||||
#
|
||||
# === 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 month_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "month"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "week".
|
||||
#
|
||||
# === 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 week_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "week"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "url".
|
||||
#
|
||||
# ==== Options
|
||||
|
|
|
@ -8,14 +8,18 @@ module ActionView
|
|||
autoload :CollectionCheckBoxes
|
||||
autoload :CollectionRadioButtons
|
||||
autoload :CollectionSelect
|
||||
autoload :ColorField
|
||||
autoload :DateField
|
||||
autoload :DateSelect
|
||||
autoload :DatetimeField
|
||||
autoload :DatetimeLocalField
|
||||
autoload :DatetimeSelect
|
||||
autoload :EmailField
|
||||
autoload :FileField
|
||||
autoload :GroupedCollectionSelect
|
||||
autoload :HiddenField
|
||||
autoload :Label
|
||||
autoload :MonthField
|
||||
autoload :NumberField
|
||||
autoload :PasswordField
|
||||
autoload :RadioButton
|
||||
|
@ -29,6 +33,7 @@ module ActionView
|
|||
autoload :TimeSelect
|
||||
autoload :TimeZoneSelect
|
||||
autoload :UrlField
|
||||
autoload :WeekField
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
25
actionpack/lib/action_view/helpers/tags/color_field.rb
Normal file
25
actionpack/lib/action_view/helpers/tags/color_field.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
module ActionView
|
||||
module Helpers
|
||||
module Tags
|
||||
class ColorField < TextField #:nodoc:
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
options["value"] = @options.fetch("value") { validate_color_string(value(object)) }
|
||||
@options = options
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_color_string(string)
|
||||
regex = /#[0-9a-fA-F]{6}/
|
||||
if regex.match(string)
|
||||
string.downcase
|
||||
else
|
||||
"#000000"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
22
actionpack/lib/action_view/helpers/tags/datetime_field.rb
Normal file
22
actionpack/lib/action_view/helpers/tags/datetime_field.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
module ActionView
|
||||
module Helpers
|
||||
module Tags
|
||||
class DatetimeField < TextField #:nodoc:
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
options["value"] = @options.fetch("value") { format_global_date_time_string(value(object)) }
|
||||
options["min"] = format_global_date_time_string(options["min"])
|
||||
options["max"] = format_global_date_time_string(options["max"])
|
||||
@options = options
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_global_date_time_string(value)
|
||||
value.try(:strftime, "%Y-%m-%dT%T.%L%z")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
module ActionView
|
||||
module Helpers
|
||||
module Tags
|
||||
class DatetimeLocalField < TextField #:nodoc:
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
options["type"] = "datetime-local"
|
||||
options["value"] = @options.fetch("value") { format_local_date_time_string(value(object)) }
|
||||
options["min"] = format_local_date_time_string(options["min"])
|
||||
options["max"] = format_local_date_time_string(options["max"])
|
||||
@options = options
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_local_date_time_string(value)
|
||||
value.try(:strftime, "%Y-%m-%dT%T")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
22
actionpack/lib/action_view/helpers/tags/month_field.rb
Normal file
22
actionpack/lib/action_view/helpers/tags/month_field.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
module ActionView
|
||||
module Helpers
|
||||
module Tags
|
||||
class MonthField < TextField #:nodoc:
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
options["value"] = @options.fetch("value") { format_month_string(value(object)) }
|
||||
options["min"] = format_month_string(options["min"])
|
||||
options["max"] = format_month_string(options["max"])
|
||||
@options = options
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_month_string(value)
|
||||
value.try(:strftime, "%Y-%m")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
22
actionpack/lib/action_view/helpers/tags/week_field.rb
Normal file
22
actionpack/lib/action_view/helpers/tags/week_field.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
module ActionView
|
||||
module Helpers
|
||||
module Tags
|
||||
class WeekField < TextField #:nodoc:
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
options["value"] = @options.fetch("value") { format_week_string(value(object)) }
|
||||
options["min"] = format_week_string(options["min"])
|
||||
options["max"] = format_week_string(options["max"])
|
||||
@options = options
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format_week_string(value)
|
||||
value.try(:strftime, "%Y-W%W")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -214,3 +214,6 @@ class RenderJsonTestException < Exception
|
|||
return { :error => self.class.name, :message => self.to_s }.to_json
|
||||
end
|
||||
end
|
||||
|
||||
class Car < Struct.new(:color)
|
||||
end
|
||||
|
|
|
@ -83,6 +83,8 @@ class FormHelperTest < ActionView::TestCase
|
|||
@post.tags << Tag.new
|
||||
|
||||
@blog_post = Blog::Post.new("And his name will be forty and four.", 44)
|
||||
|
||||
@car = Car.new("#000FFF")
|
||||
end
|
||||
|
||||
Routes = ActionDispatch::Routing::RouteSet.new
|
||||
|
@ -610,6 +612,17 @@ class FormHelperTest < ActionView::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_color_field_with_valid_hex_color_string
|
||||
expected = %{<input id="car_color" name="car[color]" type="color" value="#000fff" />}
|
||||
assert_dom_equal(expected, color_field("car", "color"))
|
||||
end
|
||||
|
||||
def test_color_field_with_invalid_hex_color_string
|
||||
expected = %{<input id="car_color" name="car[color]" type="color" value="#000000" />}
|
||||
@car.color = "#1234TR"
|
||||
assert_dom_equal(expected, color_field("car", "color"))
|
||||
end
|
||||
|
||||
def test_search_field
|
||||
expected = %{<input id="contact_notes_query" name="contact[notes_query]" type="search" />}
|
||||
assert_dom_equal(expected, search_field("contact", "notes_query"))
|
||||
|
@ -672,6 +685,146 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal(expected, time_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_field
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T00:00:00.000+0000" />}
|
||||
assert_dom_equal(expected, datetime_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_field_with_datetime_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
assert_dom_equal(expected, datetime_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_field_with_extra_attrs
|
||||
expected = %{<input id="post_written_on" step="60" max="2010-08-15T10:25:00.000+0000" min="2000-06-15T20:45:30.000+0000" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
|
||||
@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)
|
||||
step = 60
|
||||
assert_dom_equal(expected, datetime_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
|
||||
end
|
||||
|
||||
def test_datetime_field_with_timewithzone_value
|
||||
previous_time_zone, Time.zone = Time.zone, 'UTC'
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T15:30:45.000+0000" />}
|
||||
@post.written_on = Time.zone.parse('2004-06-15 15:30:45')
|
||||
assert_dom_equal(expected, datetime_field("post", "written_on"))
|
||||
ensure
|
||||
Time.zone = previous_time_zone
|
||||
end
|
||||
|
||||
def test_datetime_field_with_nil_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" />}
|
||||
@post.written_on = nil
|
||||
assert_dom_equal(expected, datetime_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_local_field
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T00:00:00" />}
|
||||
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_local_field_with_datetime_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_datetime_local_field_with_extra_attrs
|
||||
expected = %{<input id="post_written_on" step="60" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
|
||||
@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)
|
||||
step = 60
|
||||
assert_dom_equal(expected, datetime_local_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
|
||||
end
|
||||
|
||||
def test_datetime_local_field_with_timewithzone_value
|
||||
previous_time_zone, Time.zone = Time.zone, 'UTC'
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T15:30:45" />}
|
||||
@post.written_on = Time.zone.parse('2004-06-15 15:30:45')
|
||||
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
|
||||
ensure
|
||||
Time.zone = previous_time_zone
|
||||
end
|
||||
|
||||
def test_datetime_local_field_with_nil_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" />}
|
||||
@post.written_on = nil
|
||||
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_month_field
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="month" value="2004-06" />}
|
||||
assert_dom_equal(expected, month_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_month_field_with_nil_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="month" />}
|
||||
@post.written_on = nil
|
||||
assert_dom_equal(expected, month_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_month_field_with_datetime_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="month" value="2004-06" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
assert_dom_equal(expected, month_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_month_field_with_extra_attrs
|
||||
expected = %{<input id="post_written_on" step="2" max="2010-12" min="2000-02" name="post[written_on]" type="month" value="2004-06" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
min_value = DateTime.new(2000, 2, 13)
|
||||
max_value = DateTime.new(2010, 12, 23)
|
||||
step = 2
|
||||
assert_dom_equal(expected, month_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
|
||||
end
|
||||
|
||||
def test_month_field_with_timewithzone_value
|
||||
previous_time_zone, Time.zone = Time.zone, 'UTC'
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="month" value="2004-06" />}
|
||||
@post.written_on = Time.zone.parse('2004-06-15 15:30:45')
|
||||
assert_dom_equal(expected, month_field("post", "written_on"))
|
||||
ensure
|
||||
Time.zone = previous_time_zone
|
||||
end
|
||||
|
||||
def test_week_field
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="week" value="2004-W24" />}
|
||||
assert_dom_equal(expected, week_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_week_field_with_nil_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="week" />}
|
||||
@post.written_on = nil
|
||||
assert_dom_equal(expected, week_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_week_field_with_datetime_value
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="week" value="2004-W24" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
assert_dom_equal(expected, week_field("post", "written_on"))
|
||||
end
|
||||
|
||||
def test_week_field_with_extra_attrs
|
||||
expected = %{<input id="post_written_on" step="2" max="2010-W51" min="2000-W06" name="post[written_on]" type="week" value="2004-W24" />}
|
||||
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
|
||||
min_value = DateTime.new(2000, 2, 13)
|
||||
max_value = DateTime.new(2010, 12, 23)
|
||||
step = 2
|
||||
assert_dom_equal(expected, week_field("post", "written_on", :min => min_value, :max => max_value, :step => step))
|
||||
end
|
||||
|
||||
def test_week_field_with_timewithzone_value
|
||||
previous_time_zone, Time.zone = Time.zone, 'UTC'
|
||||
expected = %{<input id="post_written_on" name="post[written_on]" type="week" value="2004-W24" />}
|
||||
@post.written_on = Time.zone.parse('2004-06-15 15:30:45')
|
||||
assert_dom_equal(expected, week_field("post", "written_on"))
|
||||
ensure
|
||||
Time.zone = previous_time_zone
|
||||
end
|
||||
|
||||
def test_url_field
|
||||
expected = %{<input id="user_homepage" name="user[homepage]" type="url" />}
|
||||
assert_dom_equal(expected, url_field("user", "homepage"))
|
||||
|
|
|
@ -444,6 +444,11 @@ class FormTagHelperTest < ActionView::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_color_field_tag
|
||||
expected = %{<input id="car" name="car" type="color" />}
|
||||
assert_dom_equal(expected, color_field_tag("car"))
|
||||
end
|
||||
|
||||
def test_search_field_tag
|
||||
expected = %{<input id="query" name="query" type="search" />}
|
||||
assert_dom_equal(expected, search_field_tag("query"))
|
||||
|
@ -464,6 +469,26 @@ class FormTagHelperTest < ActionView::TestCase
|
|||
assert_dom_equal(expected, time_field_tag("cell"))
|
||||
end
|
||||
|
||||
def test_datetime_field_tag
|
||||
expected = %{<input id="appointment" name="appointment" type="datetime" />}
|
||||
assert_dom_equal(expected, datetime_field_tag("appointment"))
|
||||
end
|
||||
|
||||
def test_datetime_local_field_tag
|
||||
expected = %{<input id="appointment" name="appointment" type="datetime-local" />}
|
||||
assert_dom_equal(expected, datetime_local_field_tag("appointment"))
|
||||
end
|
||||
|
||||
def test_month_field_tag
|
||||
expected = %{<input id="birthday" name="birthday" type="month" />}
|
||||
assert_dom_equal(expected, month_field_tag("birthday"))
|
||||
end
|
||||
|
||||
def test_week_field_tag
|
||||
expected = %{<input id="birthday" name="birthday" type="week" />}
|
||||
assert_dom_equal(expected, week_field_tag("birthday"))
|
||||
end
|
||||
|
||||
def test_url_field_tag
|
||||
expected = %{<input id="homepage" name="homepage" type="url" />}
|
||||
assert_dom_equal(expected, url_field_tag("homepage"))
|
||||
|
|
|
@ -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, time 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, color fields, datetime fields, datetime-local fields, month fields, week fields, URL fields and email fields:
|
||||
|
||||
<erb>
|
||||
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
|
||||
|
@ -159,8 +159,13 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel
|
|||
<%= search_field(:user, :name) %>
|
||||
<%= telephone_field(:user, :phone) %>
|
||||
<%= date_field(:user, :born_on) %>
|
||||
<%= datetime_field(:user, :meeting_time) %>
|
||||
<%= datetime_local_field(:user, :graduation_day) %>
|
||||
<%= month_field(:user, :birthday_month) %>
|
||||
<%= week_field(:user, :birthday_week) %>
|
||||
<%= url_field(:user, :homepage) %>
|
||||
<%= email_field(:user, :address) %>
|
||||
<%= color_field(:user, :favorite_color) %>
|
||||
<%= time_field(:task, :started_at) %>
|
||||
</erb>
|
||||
|
||||
|
@ -173,14 +178,19 @@ Output:
|
|||
<input id="user_name" name="user[name]" type="search" />
|
||||
<input id="user_phone" name="user[phone]" type="tel" />
|
||||
<input id="user_born_on" name="user[born_on]" type="date" />
|
||||
<input id="user_meeting_time" name="user[meeting_time]" type="datetime" />
|
||||
<input id="user_graduation_day" name="user[graduation_day]" type="datetime-local" />
|
||||
<input id="user_birthday_month" name="user[birthday_month]" type="month" />
|
||||
<input id="user_birthday_week" name="user[birthday_week]" type="week" />
|
||||
<input id="user_homepage" name="user[homepage]" type="url" />
|
||||
<input id="user_address" name="user[address]" type="email" />
|
||||
<input id="user_favorite_color" name="user[favorite_color]" type="color" value="#000000" />
|
||||
<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, 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.
|
||||
IMPORTANT: The search, telephone, date, time, color, datetime, datetime-local, month, week, 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.
|
||||
|
||||
|
|
Loading…
Reference in a new issue