actionview 4.1.16 → 4.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionview might be problematic. Click here for more details.

Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +85 -483
  3. data/README.rdoc +7 -2
  4. data/lib/action_view.rb +0 -1
  5. data/lib/action_view/base.rb +2 -10
  6. data/lib/action_view/digestor.rb +1 -1
  7. data/lib/action_view/gem_version.rb +3 -3
  8. data/lib/action_view/helpers/asset_tag_helper.rb +32 -25
  9. data/lib/action_view/helpers/asset_url_helper.rb +29 -18
  10. data/lib/action_view/helpers/cache_helper.rb +2 -2
  11. data/lib/action_view/helpers/capture_helper.rb +1 -12
  12. data/lib/action_view/helpers/date_helper.rb +16 -12
  13. data/lib/action_view/helpers/debug_helper.rb +7 -11
  14. data/lib/action_view/helpers/form_helper.rb +65 -13
  15. data/lib/action_view/helpers/form_options_helper.rb +3 -3
  16. data/lib/action_view/helpers/form_tag_helper.rb +137 -28
  17. data/lib/action_view/helpers/javascript_helper.rb +7 -1
  18. data/lib/action_view/helpers/number_helper.rb +8 -10
  19. data/lib/action_view/helpers/output_safety_helper.rb +6 -6
  20. data/lib/action_view/helpers/rendering_helper.rb +6 -6
  21. data/lib/action_view/helpers/sanitize_helper.rb +67 -109
  22. data/lib/action_view/helpers/tag_helper.rb +15 -5
  23. data/lib/action_view/helpers/tags/base.rb +1 -1
  24. data/lib/action_view/helpers/tags/collection_check_boxes.rb +5 -1
  25. data/lib/action_view/helpers/tags/collection_helpers.rb +1 -1
  26. data/lib/action_view/helpers/tags/datetime_field.rb +10 -2
  27. data/lib/action_view/helpers/tags/label.rb +3 -3
  28. data/lib/action_view/helpers/tags/placeholderable.rb +32 -0
  29. data/lib/action_view/helpers/tags/text_area.rb +4 -0
  30. data/lib/action_view/helpers/tags/text_field.rb +4 -1
  31. data/lib/action_view/helpers/tags/week_field.rb +1 -1
  32. data/lib/action_view/helpers/text_helper.rb +25 -8
  33. data/lib/action_view/helpers/translation_helper.rb +29 -25
  34. data/lib/action_view/helpers/url_helper.rb +13 -14
  35. data/lib/action_view/log_subscriber.rb +5 -5
  36. data/lib/action_view/lookup_context.rb +6 -12
  37. data/lib/action_view/model_naming.rb +1 -1
  38. data/lib/action_view/path_set.rb +7 -19
  39. data/lib/action_view/renderer/abstract_renderer.rb +5 -3
  40. data/lib/action_view/renderer/partial_renderer.rb +76 -38
  41. data/lib/action_view/renderer/renderer.rb +0 -4
  42. data/lib/action_view/renderer/template_renderer.rb +5 -6
  43. data/lib/action_view/rendering.rb +7 -6
  44. data/lib/action_view/routing_url_for.rb +13 -5
  45. data/lib/action_view/tasks/dependencies.rake +7 -9
  46. data/lib/action_view/template/handlers.rb +9 -0
  47. data/lib/action_view/template/resolver.rb +7 -24
  48. data/lib/action_view/test_case.rb +13 -7
  49. data/lib/action_view/testing/resolvers.rb +2 -2
  50. data/lib/action_view/view_paths.rb +26 -15
  51. metadata +52 -18
  52. data/lib/action_view/vendor/html-scanner.rb +0 -20
  53. data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
  54. data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
  55. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
  56. data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
  57. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
  58. data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
@@ -142,7 +142,7 @@ module ActionView
142
142
  # will get expanded to
143
143
  #
144
144
  # <%= text_field :person, :first_name %>
145
- # which results in an html <tt><input></tt> tag whose +name+ attribute is
145
+ # which results in an HTML <tt><input></tt> tag whose +name+ attribute is
146
146
  # <tt>person[first_name]</tt>. This means that when the form is submitted,
147
147
  # the value entered by the user will be available in the controller as
148
148
  # <tt>params[:person][:first_name]</tt>.
@@ -434,7 +434,8 @@ module ActionView
434
434
  output = capture(builder, &block)
435
435
  html_options[:multipart] ||= builder.multipart?
436
436
 
437
- form_tag(options[:url] || {}, html_options) { output }
437
+ html_options = html_options_for_form(options[:url] || {}, html_options)
438
+ form_tag_with_body(html_options, output)
438
439
  end
439
440
 
440
441
  def apply_form_for_options!(record, object, options) #:nodoc:
@@ -449,7 +450,11 @@ module ActionView
449
450
  method: method
450
451
  )
451
452
 
452
- options[:url] ||= polymorphic_path(record, format: options.delete(:format))
453
+ options[:url] ||= if options.key?(:format)
454
+ polymorphic_path(record, format: options.delete(:format))
455
+ else
456
+ polymorphic_path(record, {})
457
+ end
453
458
  end
454
459
  private :apply_form_for_options!
455
460
 
@@ -457,7 +462,7 @@ module ActionView
457
462
  # doesn't create the form tags themselves. This makes fields_for suitable
458
463
  # for specifying additional model objects in the same form.
459
464
  #
460
- # Although the usage and purpose of +field_for+ is similar to +form_for+'s,
465
+ # Although the usage and purpose of +fields_for+ is similar to +form_for+'s,
461
466
  # its method signature is slightly different. Like +form_for+, it yields
462
467
  # a FormBuilder object associated with a particular model object to a block,
463
468
  # and within the block allows methods to be called on the builder to
@@ -477,7 +482,7 @@ module ActionView
477
482
  # Admin? : <%= permission_fields.check_box :admin %>
478
483
  # <% end %>
479
484
  #
480
- # <%= f.submit %>
485
+ # <%= person_form.submit %>
481
486
  # <% end %>
482
487
  #
483
488
  # In this case, the checkbox field will be represented by an HTML +input+
@@ -746,6 +751,7 @@ module ActionView
746
751
  # label(:post, :terms) do
747
752
  # 'Accept <a href="/terms">Terms</a>.'.html_safe
748
753
  # end
754
+ # # => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
749
755
  def label(object_name, method, content_or_options = nil, options = nil, &block)
750
756
  Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
751
757
  end
@@ -1007,6 +1013,18 @@ module ActionView
1007
1013
  # date_field("user", "born_on", value: "1984-05-12")
1008
1014
  # # => <input id="user_born_on" name="user[born_on]" type="date" value="1984-05-12" />
1009
1015
  #
1016
+ # You can create values for the "min" and "max" attributes by passing
1017
+ # instances of Date or Time to the options hash.
1018
+ #
1019
+ # date_field("user", "born_on", min: Date.today)
1020
+ # # => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
1021
+ #
1022
+ # Alternatively, you can pass a String formatted as an ISO8601 date as the
1023
+ # values for "min" and "max."
1024
+ #
1025
+ # date_field("user", "born_on", min: "2014-05-20")
1026
+ # # => <input id="user_born_on" name="user[born_on]" type="date" min="2014-05-20" />
1027
+ #
1010
1028
  def date_field(object_name, method, options = {})
1011
1029
  Tags::DateField.new(object_name, method, self, options).render
1012
1030
  end
@@ -1024,6 +1042,18 @@ module ActionView
1024
1042
  # time_field("task", "started_at")
1025
1043
  # # => <input id="task_started_at" name="task[started_at]" type="time" />
1026
1044
  #
1045
+ # You can create values for the "min" and "max" attributes by passing
1046
+ # instances of Date or Time to the options hash.
1047
+ #
1048
+ # time_field("task", "started_at", min: Time.now)
1049
+ # # => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
1050
+ #
1051
+ # Alternatively, you can pass a String formatted as an ISO8601 time as the
1052
+ # values for "min" and "max."
1053
+ #
1054
+ # time_field("task", "started_at", min: "01:00:00")
1055
+ # # => <input id="task_started_at" name="task[started_at]" type="time" min="01:00:00.000" />
1056
+ #
1027
1057
  def time_field(object_name, method, options = {})
1028
1058
  Tags::TimeField.new(object_name, method, self, options).render
1029
1059
  end
@@ -1041,6 +1071,18 @@ module ActionView
1041
1071
  # datetime_field("user", "born_on")
1042
1072
  # # => <input id="user_born_on" name="user[born_on]" type="datetime" value="1984-01-12T00:00:00.000+0000" />
1043
1073
  #
1074
+ # You can create values for the "min" and "max" attributes by passing
1075
+ # instances of Date or Time to the options hash.
1076
+ #
1077
+ # datetime_field("user", "born_on", min: Date.today)
1078
+ # # => <input id="user_born_on" name="user[born_on]" type="datetime" min="2014-05-20T00:00:00.000+0000" />
1079
+ #
1080
+ # Alternatively, you can pass a String formatted as an ISO8601 datetime
1081
+ # with UTC offset as the values for "min" and "max."
1082
+ #
1083
+ # datetime_field("user", "born_on", min: "2014-05-20T00:00:00+0000")
1084
+ # # => <input id="user_born_on" name="user[born_on]" type="datetime" min="2014-05-20T00:00:00.000+0000" />
1085
+ #
1044
1086
  def datetime_field(object_name, method, options = {})
1045
1087
  Tags::DatetimeField.new(object_name, method, self, options).render
1046
1088
  end
@@ -1058,6 +1100,18 @@ module ActionView
1058
1100
  # datetime_local_field("user", "born_on")
1059
1101
  # # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
1060
1102
  #
1103
+ # You can create values for the "min" and "max" attributes by passing
1104
+ # instances of Date or Time to the options hash.
1105
+ #
1106
+ # datetime_local_field("user", "born_on", min: Date.today)
1107
+ # # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
1108
+ #
1109
+ # Alternatively, you can pass a String formatted as an ISO8601 datetime as
1110
+ # the values for "min" and "max."
1111
+ #
1112
+ # datetime_local_field("user", "born_on", min: "2014-05-20T00:00:00")
1113
+ # # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
1114
+ #
1061
1115
  def datetime_local_field(object_name, method, options = {})
1062
1116
  Tags::DatetimeLocalField.new(object_name, method, self, options).render
1063
1117
  end
@@ -1142,11 +1196,11 @@ module ActionView
1142
1196
  object_name = model_name_from_record_or_class(object).param_key
1143
1197
  end
1144
1198
 
1145
- builder = options[:builder] || default_form_builder_class
1199
+ builder = options[:builder] || default_form_builder
1146
1200
  builder.new(object_name, object, self, options)
1147
1201
  end
1148
1202
 
1149
- def default_form_builder_class
1203
+ def default_form_builder
1150
1204
  builder = ActionView::Base.default_form_builder
1151
1205
  builder.respond_to?(:constantize) ? builder.constantize : builder
1152
1206
  end
@@ -1268,7 +1322,7 @@ module ActionView
1268
1322
  # doesn't create the form tags themselves. This makes fields_for suitable
1269
1323
  # for specifying additional model objects in the same form.
1270
1324
  #
1271
- # Although the usage and purpose of +field_for+ is similar to +form_for+'s,
1325
+ # Although the usage and purpose of +fields_for+ is similar to +form_for+'s,
1272
1326
  # its method signature is slightly different. Like +form_for+, it yields
1273
1327
  # a FormBuilder object associated with a particular model object to a block,
1274
1328
  # and within the block allows methods to be called on the builder to
@@ -1809,8 +1863,8 @@ module ActionView
1809
1863
  object = convert_to_model(@object)
1810
1864
  key = object ? (object.persisted? ? :update : :create) : :submit
1811
1865
 
1812
- model = if object.class.respond_to?(:model_name)
1813
- object.class.model_name.human
1866
+ model = if object.respond_to?(:model_name)
1867
+ object.model_name.human
1814
1868
  else
1815
1869
  @object_name.to_s.humanize
1816
1870
  end
@@ -1871,8 +1925,6 @@ module ActionView
1871
1925
  end
1872
1926
 
1873
1927
  ActiveSupport.on_load(:action_view) do
1874
- cattr_accessor(:default_form_builder, instance_writer: false, instance_reader: false) do
1875
- ::ActionView::Helpers::FormBuilder
1876
- end
1928
+ cattr_accessor(:default_form_builder) { ::ActionView::Helpers::FormBuilder }
1877
1929
  end
1878
1930
  end
@@ -314,7 +314,7 @@ module ActionView
314
314
  # # => <option>MasterCard</option>
315
315
  # # => <option selected="selected">Discover</option>
316
316
  #
317
- # You can optionally provide html attributes as the last element of the array.
317
+ # You can optionally provide HTML attributes as the last element of the array.
318
318
  #
319
319
  # options_for_select([ "Denmark", ["USA", {class: 'bold'}], "Sweden" ], ["USA", "Sweden"])
320
320
  # # => <option value="Denmark">Denmark</option>
@@ -633,7 +633,7 @@ module ActionView
633
633
  # even use the label as wrapper, as in the example above.
634
634
  #
635
635
  # The builder methods <tt>label</tt> and <tt>radio_button</tt> also accept
636
- # extra html options:
636
+ # extra HTML options:
637
637
  # collection_radio_buttons(:post, :author_id, Author.all, :id, :name_with_initial) do |b|
638
638
  # b.label(class: "radio_button") { b.radio_button(class: "radio_button") }
639
639
  # end
@@ -696,7 +696,7 @@ module ActionView
696
696
  # use the label as wrapper, as in the example above.
697
697
  #
698
698
  # The builder methods <tt>label</tt> and <tt>check_box</tt> also accept
699
- # extra html options:
699
+ # extra HTML options:
700
700
  # collection_check_boxes(:post, :author_ids, Author.all, :id, :name_with_initial) do |b|
701
701
  # b.label(class: "check_box") { b.check_box(class: "check_box") }
702
702
  # end
@@ -35,10 +35,10 @@ module ActionView
35
35
  # This is helpful when you're fragment-caching the form. Remote forms get the
36
36
  # authenticity token from the <tt>meta</tt> tag, so embedding is unnecessary unless you
37
37
  # support browsers without JavaScript.
38
+ # * A list of parameters to feed to the URL the form will be posted to.
38
39
  # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
39
40
  # submit behavior. By default this behavior is an ajax submit.
40
41
  # * <tt>:enforce_utf8</tt> - If set to false, a hidden input with name utf8 is not output.
41
- # * Any other key creates standard HTML attributes for the tag.
42
42
  #
43
43
  # ==== Examples
44
44
  # form_tag('/posts')
@@ -67,7 +67,7 @@ module ActionView
67
67
  def form_tag(url_for_options = {}, options = {}, &block)
68
68
  html_options = html_options_for_form(url_for_options, options)
69
69
  if block_given?
70
- form_tag_in_block(html_options, &block)
70
+ form_tag_with_body(html_options, capture(&block))
71
71
  else
72
72
  form_tag_html(html_options)
73
73
  end
@@ -82,14 +82,18 @@ module ActionView
82
82
  # ==== Options
83
83
  # * <tt>:multiple</tt> - If set to true the selection will allow multiple choices.
84
84
  # * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
85
- # * <tt>:include_blank</tt> - If set to true, an empty option will be created.
86
- # * <tt>:prompt</tt> - Create a prompt option with blank value and the text asking user to select something
85
+ # * <tt>:include_blank</tt> - If set to true, an empty option will be created. If set to a string, the string will be used as the option's content and the value will be empty.
86
+ # * <tt>:prompt</tt> - Create a prompt option with blank value and the text asking user to select something.
87
+ # * <tt>:selected</tt> - Provide a default selected value. It should be of the exact type as the provided options.
87
88
  # * Any other key creates standard HTML attributes for the tag.
88
89
  #
89
90
  # ==== Examples
90
91
  # select_tag "people", options_from_collection_for_select(@people, "id", "name")
91
92
  # # <select id="people" name="people"><option value="1">David</option></select>
92
93
  #
94
+ # select_tag "people", options_from_collection_for_select(@people, "id", "name"), selected: ["1", "David"]
95
+ # # <select id="people" name="people"><option value="1" selected="selected">David</option></select>
96
+ #
93
97
  # select_tag "people", "<option>David</option>".html_safe
94
98
  # # => <select id="people" name="people"><option>David</option></select>
95
99
  #
@@ -105,13 +109,16 @@ module ActionView
105
109
  # # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
106
110
  # # <option>Out</option></select>
107
111
  #
108
- # select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, class: 'form_input'
109
- # # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
112
+ # select_tag "access", "<option>Read</option><option>Write</option>".html_safe, multiple: true, class: 'form_input', id: 'unique_id'
113
+ # # => <select class="form_input" id="unique_id" multiple="multiple" name="access[]"><option>Read</option>
110
114
  # # <option>Write</option></select>
111
115
  #
112
116
  # select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: true
113
117
  # # => <select id="people" name="people"><option value=""></option><option value="1">David</option></select>
114
118
  #
119
+ # select_tag "people", options_from_collection_for_select(@people, "id", "name"), include_blank: "All"
120
+ # # => <select id="people" name="people"><option value="">All</option><option value="1">David</option></select>
121
+ #
115
122
  # select_tag "people", options_from_collection_for_select(@people, "id", "name"), prompt: "Select something"
116
123
  # # => <select id="people" name="people"><option value="">Select something</option><option value="1">David</option></select>
117
124
  #
@@ -126,20 +133,12 @@ module ActionView
126
133
  option_tags ||= ""
127
134
  html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
128
135
 
129
- if options.include?(:include_blank)
130
- include_blank = options.delete(:include_blank)
131
-
132
- if include_blank == true
133
- include_blank = ''
134
- end
135
-
136
- if include_blank
137
- option_tags = content_tag(:option, include_blank, value: '').safe_concat(option_tags)
138
- end
136
+ if options.delete(:include_blank)
137
+ option_tags = content_tag(:option, '', :value => '').safe_concat(option_tags)
139
138
  end
140
139
 
141
140
  if prompt = options.delete(:prompt)
142
- option_tags = content_tag(:option, prompt, value: '').safe_concat(option_tags)
141
+ option_tags = content_tag(:option, prompt, :value => '').safe_concat(option_tags)
143
142
  end
144
143
 
145
144
  content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
@@ -509,19 +508,19 @@ module ActionView
509
508
  #
510
509
  # ==== Examples
511
510
  # image_submit_tag("login.png")
512
- # # => <input alt="Login" src="/images/login.png" type="image" />
511
+ # # => <input alt="Login" src="/assets/login.png" type="image" />
513
512
  #
514
513
  # image_submit_tag("purchase.png", disabled: true)
515
- # # => <input alt="Purchase" disabled="disabled" src="/images/purchase.png" type="image" />
514
+ # # => <input alt="Purchase" disabled="disabled" src="/assets/purchase.png" type="image" />
516
515
  #
517
516
  # image_submit_tag("search.png", class: 'search_button', alt: 'Find')
518
- # # => <input alt="Find" class="search_button" src="/images/search.png" type="image" />
517
+ # # => <input alt="Find" class="search_button" src="/assets/search.png" type="image" />
519
518
  #
520
519
  # image_submit_tag("agree.png", disabled: true, class: "agree_disagree_button")
521
- # # => <input alt="Agree" class="agree_disagree_button" disabled="disabled" src="/images/agree.png" type="image" />
520
+ # # => <input alt="Agree" class="agree_disagree_button" disabled="disabled" src="/assets/agree.png" type="image" />
522
521
  #
523
522
  # image_submit_tag("save.png", data: { confirm: "Are you sure?" })
524
- # # => <input alt="Save" src="/images/save.png" data-confirm="Are you sure?" type="image" />
523
+ # # => <input alt="Save" src="/assets/save.png" data-confirm="Are you sure?" type="image" />
525
524
  def image_submit_tag(source, options = {})
526
525
  options = options.stringify_keys
527
526
  tag :input, { "alt" => image_alt(source), "type" => "image", "src" => path_to_image(source) }.update(options)
@@ -558,6 +557,19 @@ module ActionView
558
557
  #
559
558
  # ==== Options
560
559
  # * Accepts the same options as text_field_tag.
560
+ #
561
+ # ==== Examples
562
+ # color_field_tag 'name'
563
+ # # => <input id="name" name="name" type="color" />
564
+ #
565
+ # color_field_tag 'color', '#DEF726'
566
+ # # => <input id="color" name="color" type="color" value="#DEF726" />
567
+ #
568
+ # color_field_tag 'color', nil, class: 'special_input'
569
+ # # => <input class="special_input" id="color" name="color" type="color" />
570
+ #
571
+ # color_field_tag 'color', '#DEF726', class: 'special_input', disabled: true
572
+ # # => <input disabled="disabled" class="special_input" id="color" name="color" type="color" value="#DEF726" />
561
573
  def color_field_tag(name, value = nil, options = {})
562
574
  text_field_tag(name, value, options.stringify_keys.update("type" => "color"))
563
575
  end
@@ -566,6 +578,19 @@ module ActionView
566
578
  #
567
579
  # ==== Options
568
580
  # * Accepts the same options as text_field_tag.
581
+ #
582
+ # ==== Examples
583
+ # search_field_tag 'name'
584
+ # # => <input id="name" name="name" type="search" />
585
+ #
586
+ # search_field_tag 'search', 'Enter your search query here'
587
+ # # => <input id="search" name="search" type="search" value="Enter your search query here" />
588
+ #
589
+ # search_field_tag 'search', nil, class: 'special_input'
590
+ # # => <input class="special_input" id="search" name="search" type="search" />
591
+ #
592
+ # search_field_tag 'search', 'Enter your search query here', class: 'special_input', disabled: true
593
+ # # => <input disabled="disabled" class="special_input" id="search" name="search" type="search" value="Enter your search query here" />
569
594
  def search_field_tag(name, value = nil, options = {})
570
595
  text_field_tag(name, value, options.stringify_keys.update("type" => "search"))
571
596
  end
@@ -574,6 +599,19 @@ module ActionView
574
599
  #
575
600
  # ==== Options
576
601
  # * Accepts the same options as text_field_tag.
602
+ #
603
+ # ==== Examples
604
+ # telephone_field_tag 'name'
605
+ # # => <input id="name" name="name" type="tel" />
606
+ #
607
+ # telephone_field_tag 'tel', '0123456789'
608
+ # # => <input id="tel" name="tel" type="tel" value="0123456789" />
609
+ #
610
+ # telephone_field_tag 'tel', nil, class: 'special_input'
611
+ # # => <input class="special_input" id="tel" name="tel" type="tel" />
612
+ #
613
+ # telephone_field_tag 'tel', '0123456789', class: 'special_input', disabled: true
614
+ # # => <input disabled="disabled" class="special_input" id="tel" name="tel" type="tel" value="0123456789" />
577
615
  def telephone_field_tag(name, value = nil, options = {})
578
616
  text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
579
617
  end
@@ -583,6 +621,19 @@ module ActionView
583
621
  #
584
622
  # ==== Options
585
623
  # * Accepts the same options as text_field_tag.
624
+ #
625
+ # ==== Examples
626
+ # date_field_tag 'name'
627
+ # # => <input id="name" name="name" type="date" />
628
+ #
629
+ # date_field_tag 'date', '01/01/2014'
630
+ # # => <input id="date" name="date" type="date" value="01/01/2014" />
631
+ #
632
+ # date_field_tag 'date', nil, class: 'special_input'
633
+ # # => <input class="special_input" id="date" name="date" type="date" />
634
+ #
635
+ # date_field_tag 'date', '01/01/2014', class: 'special_input', disabled: true
636
+ # # => <input disabled="disabled" class="special_input" id="date" name="date" type="date" value="01/01/2014" />
586
637
  def date_field_tag(name, value = nil, options = {})
587
638
  text_field_tag(name, value, options.stringify_keys.update("type" => "date"))
588
639
  end
@@ -646,6 +697,19 @@ module ActionView
646
697
  #
647
698
  # ==== Options
648
699
  # * Accepts the same options as text_field_tag.
700
+ #
701
+ # ==== Examples
702
+ # url_field_tag 'name'
703
+ # # => <input id="name" name="name" type="url" />
704
+ #
705
+ # url_field_tag 'url', 'http://rubyonrails.org'
706
+ # # => <input id="url" name="url" type="url" value="http://rubyonrails.org" />
707
+ #
708
+ # url_field_tag 'url', nil, class: 'special_input'
709
+ # # => <input class="special_input" id="url" name="url" type="url" />
710
+ #
711
+ # url_field_tag 'url', 'http://rubyonrails.org', class: 'special_input', disabled: true
712
+ # # => <input disabled="disabled" class="special_input" id="url" name="url" type="url" value="http://rubyonrails.org" />
649
713
  def url_field_tag(name, value = nil, options = {})
650
714
  text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
651
715
  end
@@ -654,6 +718,19 @@ module ActionView
654
718
  #
655
719
  # ==== Options
656
720
  # * Accepts the same options as text_field_tag.
721
+ #
722
+ # ==== Examples
723
+ # email_field_tag 'name'
724
+ # # => <input id="name" name="name" type="email" />
725
+ #
726
+ # email_field_tag 'email', 'email@example.com'
727
+ # # => <input id="email" name="email" type="email" value="email@example.com" />
728
+ #
729
+ # email_field_tag 'email', nil, class: 'special_input'
730
+ # # => <input class="special_input" id="email" name="email" type="email" />
731
+ #
732
+ # email_field_tag 'email', 'email@example.com', class: 'special_input', disabled: true
733
+ # # => <input disabled="disabled" class="special_input" id="email" name="email" type="email" value="email@example.com" />
657
734
  def email_field_tag(name, value = nil, options = {})
658
735
  text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
659
736
  end
@@ -665,12 +742,40 @@ module ActionView
665
742
  # * <tt>:max</tt> - The maximum acceptable value.
666
743
  # * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
667
744
  # <tt>:max</tt> values.
745
+ # * <tt>:within</tt> - Same as <tt>:in</tt>.
668
746
  # * <tt>:step</tt> - The acceptable value granularity.
669
747
  # * Otherwise accepts the same options as text_field_tag.
670
748
  #
671
749
  # ==== Examples
750
+ # number_field_tag 'quantity'
751
+ # # => <input id="quantity" name="quantity" type="number" />
752
+ #
753
+ # number_field_tag 'quantity', '1'
754
+ # # => <input id="quantity" name="quantity" type="number" value="1" />
755
+ #
756
+ # number_field_tag 'quantity', nil, class: 'special_input'
757
+ # # => <input class="special_input" id="quantity" name="quantity" type="number" />
758
+ #
759
+ # number_field_tag 'quantity', nil, min: 1
760
+ # # => <input id="quantity" name="quantity" min="1" type="number" />
761
+ #
762
+ # number_field_tag 'quantity', nil, max: 9
763
+ # # => <input id="quantity" name="quantity" max="9" type="number" />
764
+ #
672
765
  # number_field_tag 'quantity', nil, in: 1...10
673
766
  # # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
767
+ #
768
+ # number_field_tag 'quantity', nil, within: 1...10
769
+ # # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
770
+ #
771
+ # number_field_tag 'quantity', nil, min: 1, max: 10
772
+ # # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
773
+ #
774
+ # number_field_tag 'quantity', nil, min: 1, max: 10, step: 2
775
+ # # => <input id="quantity" name="quantity" min="1" max="9" step="2" type="number" />
776
+ #
777
+ # number_field_tag 'quantity', '1', class: 'special_input', disabled: true
778
+ # # => <input disabled="disabled" class="special_input" id="quantity" name="quantity" type="number" value="1" />
674
779
  def number_field_tag(name, value = nil, options = {})
675
780
  options = options.stringify_keys
676
781
  options["type"] ||= "number"
@@ -691,7 +796,10 @@ module ActionView
691
796
  # Creates the hidden UTF8 enforcer tag. Override this method in a helper
692
797
  # to customize the tag.
693
798
  def utf8_enforcer_tag
694
- tag(:input, :type => "hidden", :name => "utf8", :value => "&#x2713;".html_safe)
799
+ # Use raw HTML to ensure the value is written as an HTML entity; it
800
+ # needs to be the right character regardless of which encoding the
801
+ # browser infers.
802
+ '<input name="utf8" type="hidden" value="&#x2713;" />'.html_safe
695
803
  end
696
804
 
697
805
  private
@@ -734,9 +842,11 @@ module ActionView
734
842
  method_tag(method) + token_tag(authenticity_token)
735
843
  end
736
844
 
737
- enforce_utf8 = html_options.delete("enforce_utf8") { true }
738
- tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
739
- content_tag(:div, tags, :style => 'display:none')
845
+ if html_options.delete("enforce_utf8") { true }
846
+ utf8_enforcer_tag + method_tag
847
+ else
848
+ method_tag
849
+ end
740
850
  end
741
851
 
742
852
  def form_tag_html(html_options)
@@ -744,8 +854,7 @@ module ActionView
744
854
  tag(:form, html_options, true) + extra_tags
745
855
  end
746
856
 
747
- def form_tag_in_block(html_options, &block)
748
- content = capture(&block)
857
+ def form_tag_with_body(html_options, content)
749
858
  output = form_tag_html(html_options)
750
859
  output << content
751
860
  output.safe_concat("</form>")