Skip to content
This repository
Browse code

Add HTML5 input[type="date"] helper

  • Loading branch information...
commit d6b26a6040db97a55e23a7f10f2e9ba859eb11dc 1 parent 8671802
Olek Janiszewski authored
2  actionpack/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,7 @@
1 1
 ## Rails 4.0.0 (unreleased) ##
2 2
 
  3
+*   Add `date_field` and `date_field_tag` helpers which render an `input[type="date"]` tag *Olek Janiszewski*
  4
+
3 5
 *   Adds `image_url`, `javascript_url`, `stylesheet_url`, `audio_url`, `video_url`, and `font_url`
4 6
     to assets tag helper. These URL helpers will return the full path to your assets. This is useful
5 7
     when you are going to reference this asset from external host. *Prem Sichanugrist*
18  actionpack/lib/action_view/helpers/form_helper.rb
@@ -889,6 +889,24 @@ def telephone_field(object_name, method, options = {})
889 889
       end
890 890
       alias phone_field telephone_field
891 891
 
  892
+      # Returns a text_field of type "date".
  893
+      #
  894
+      #   date_field("user", "born_on")
  895
+      #   # => <input id="user_born_on" name="user[born_on]" type="date" />
  896
+      #
  897
+      # The default value is generated by trying to call "to_date"
  898
+      # on the object's value, which makes it behave as expected for instances
  899
+      # of DateTime and ActiveSupport::TimeWithZone. You can still override that
  900
+      # by passing the "value" option explicitly, e.g.
  901
+      #
  902
+      #   @user.born_on = Date.new(1984, 1, 27)
  903
+      #   date_field("user", "born_on", value: "1984-05-12")
  904
+      #   # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
  905
+      #
  906
+      def date_field(object_name, method, options = {})
  907
+        Tags::DateField.new(object_name, method, self, options).render
  908
+      end
  909
+
892 910
       # Returns a text_field of type "url".
893 911
       #
894 912
       #   url_field("user", "homepage")
8  actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -549,6 +549,14 @@ def telephone_field_tag(name, value = nil, options = {})
549 549
       end
550 550
       alias phone_field_tag telephone_field_tag
551 551
 
  552
+      # Creates a text field of type "date".
  553
+      #
  554
+      # ==== Options
  555
+      # * Accepts the same options as text_field_tag.
  556
+      def date_field_tag(name, value = nil, options = {})
  557
+        text_field_tag(name, value, options.stringify_keys.update("type" => "date"))
  558
+      end
  559
+
552 560
       # Creates a text field of type "url".
553 561
       #
554 562
       # ==== Options
1  actionpack/lib/action_view/helpers/tags.rb
@@ -8,6 +8,7 @@ module Tags #:nodoc:
8 8
       autoload :CollectionCheckBoxes
9 9
       autoload :CollectionRadioButtons
10 10
       autoload :CollectionSelect
  11
+      autoload :DateField
11 12
       autoload :DateSelect
12 13
       autoload :DatetimeSelect
13 14
       autoload :EmailField
2  actionpack/lib/action_view/helpers/tags/base.rb
@@ -36,7 +36,7 @@ def value_before_type_cast(object)
36 36
 
37 37
             object.respond_to?(method_before_type_cast) ?
38 38
               object.send(method_before_type_cast) :
39  
-              object.send(@method_name)
  39
+              value(object)
40 40
           end
41 41
         end
42 42
 
15  actionpack/lib/action_view/helpers/tags/date_field.rb
... ...
@@ -0,0 +1,15 @@
  1
+module ActionView
  2
+  module Helpers
  3
+    module Tags
  4
+      class DateField < TextField #:nodoc:
  5
+        def render
  6
+          options = @options.stringify_keys
  7
+          options["value"] = @options.fetch("value") { value(object).try(:to_date) }
  8
+          options["size"] = nil
  9
+          @options = options
  10
+          super
  11
+        end
  12
+      end
  13
+    end
  14
+  end
  15
+end
26  actionpack/test/template/form_helper_test.rb
@@ -514,6 +514,32 @@ def test_telephone_field
514 514
     assert_dom_equal(expected, telephone_field("user", "cell"))
515 515
   end
516 516
 
  517
+  def test_date_field
  518
+    expected = %{<input id="post_written_on" name="post[written_on]" type="date" value="2004-06-15" />}
  519
+    assert_dom_equal(expected, date_field("post", "written_on"))
  520
+  end
  521
+
  522
+  def test_date_field_with_datetime_value
  523
+    expected = %{<input id="post_written_on" name="post[written_on]" type="date" value="2004-06-15" />}
  524
+    @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
  525
+    assert_dom_equal(expected, date_field("post", "written_on"))
  526
+  end
  527
+
  528
+  def test_date_field_with_timewithzone_value
  529
+    previous_time_zone, Time.zone = Time.zone, 'UTC'
  530
+    expected = %{<input id="post_written_on" name="post[written_on]" type="date" value="2004-06-15" />}
  531
+    @post.written_on = Time.zone.parse('2004-06-15 15:30:45')
  532
+    assert_dom_equal(expected, date_field("post", "written_on"))
  533
+  ensure
  534
+    Time.zone = previous_time_zone
  535
+  end
  536
+
  537
+  def test_date_field_with_nil_value
  538
+    expected = %{<input id="post_written_on" name="post[written_on]" type="date" />}
  539
+    @post.written_on = nil
  540
+    assert_dom_equal(expected, date_field("post", "written_on"))
  541
+  end
  542
+
517 543
   def test_url_field
518 544
     expected = %{<input id="user_homepage" size="30" name="user[homepage]" type="url" />}
519 545
     assert_dom_equal(expected, url_field("user", "homepage"))
7  actionpack/test/template/form_tag_helper_test.rb
@@ -457,11 +457,16 @@ def test_search_field_tag
457 457
     assert_dom_equal(expected, search_field_tag("query"))
458 458
   end
459 459
 
460  
-  def telephone_field_tag
  460
+  def test_telephone_field_tag
461 461
     expected = %{<input id="cell" name="cell" type="tel" />}
462 462
     assert_dom_equal(expected, telephone_field_tag("cell"))
463 463
   end
464 464
 
  465
+  def test_date_field_tag
  466
+    expected = %{<input id="cell" name="cell" type="date" />}
  467
+    assert_dom_equal(expected, date_field_tag("cell"))
  468
+  end
  469
+
465 470
   def test_url_field_tag
466 471
     expected = %{<input id="homepage" name="homepage" type="url" />}
467 472
     assert_dom_equal(expected, url_field_tag("homepage"))
8  railties/guides/source/form_helpers.textile
Source Rendered
@@ -150,7 +150,7 @@ NOTE: Always use labels for checkbox and radio buttons. They associate text with
150 150
 
151 151
 h4. Other Helpers of Interest
152 152
 
153  
-Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, URL fields and email fields:
  153
+Other form controls worth mentioning are textareas, password fields, hidden fields, search fields, telephone fields, date fields, URL fields and email fields:
154 154
 
155 155
 <erb>
156 156
 <%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
@@ -158,6 +158,7 @@ Other form controls worth mentioning are textareas, password fields, hidden fiel
158 158
 <%= hidden_field_tag(:parent_id, "5") %>
159 159
 <%= search_field(:user, :name) %>
160 160
 <%= telephone_field(:user, :phone) %>
  161
+<%= date_field(:user, :born_on) %>
161 162
 <%= url_field(:user, :homepage) %>
162 163
 <%= email_field(:user, :address) %>
163 164
 </erb>
@@ -170,13 +171,14 @@ Output:
170 171
 <input id="parent_id" name="parent_id" type="hidden" value="5" />
171 172
 <input id="user_name" name="user[name]" size="30" type="search" />
172 173
 <input id="user_phone" name="user[phone]" size="30" type="tel" />
  174
+<input id="user_born_on" name="user[born_on]" type="date" />
173 175
 <input id="user_homepage" size="30" name="user[homepage]" type="url" />
174 176
 <input id="user_address" size="30" name="user[address]" type="email" />
175 177
 </html>
176 178
 
177 179
 Hidden inputs are not shown to the user but instead hold data like any textual input. Values inside them can be changed with JavaScript.
178 180
 
179  
-IMPORTANT: The search, telephone, 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.
  181
+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.
180 182
 
181 183
 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.
182 184
 
@@ -467,7 +469,7 @@ Rails _used_ to have a +country_select+ helper for choosing countries, but this
467 469
 
468 470
 h3. Using Date and Time Form Helpers
469 471
 
470  
-The date and time helpers differ from all the other form helpers in two important respects:
  472
+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:
471 473
 
472 474
 # 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.
473 475
 # 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.

0 notes on commit d6b26a6

Please sign in to comment.
Something went wrong with that request. Please try again.