actionview 7.1.3.3 → 7.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -417
- data/lib/action_view/base.rb +20 -3
- data/lib/action_view/cache_expiry.rb +9 -3
- data/lib/action_view/dependency_tracker/{ripper_tracker.rb → ruby_tracker.rb} +4 -3
- data/lib/action_view/dependency_tracker.rb +1 -1
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -3
- data/lib/action_view/helpers/cache_helper.rb +4 -4
- data/lib/action_view/helpers/csrf_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +197 -192
- data/lib/action_view/helpers/form_tag_helper.rb +76 -43
- data/lib/action_view/helpers/output_safety_helper.rb +4 -4
- data/lib/action_view/helpers/tag_helper.rb +208 -18
- data/lib/action_view/helpers/url_helper.rb +4 -78
- data/lib/action_view/layouts.rb +2 -4
- data/lib/action_view/log_subscriber.rb +8 -4
- data/lib/action_view/railtie.rb +0 -1
- data/lib/action_view/render_parser/prism_render_parser.rb +127 -0
- data/lib/action_view/{ripper_ast_parser.rb → render_parser/ripper_render_parser.rb} +152 -9
- data/lib/action_view/render_parser.rb +21 -169
- data/lib/action_view/renderer/abstract_renderer.rb +1 -1
- data/lib/action_view/renderer/renderer.rb +32 -38
- data/lib/action_view/rendering.rb +4 -4
- data/lib/action_view/template/renderable.rb +7 -1
- data/lib/action_view/template/resolver.rb +0 -2
- data/lib/action_view/template.rb +28 -4
- data/lib/action_view/test_case.rb +12 -14
- data/lib/action_view/unbound_template.rb +4 -4
- data/lib/action_view.rb +1 -1
- metadata +15 -14
@@ -7,6 +7,7 @@ require "action_view/helpers/form_tag_helper"
|
|
7
7
|
require "action_view/helpers/active_model_helper"
|
8
8
|
require "action_view/model_naming"
|
9
9
|
require "action_view/record_identifier"
|
10
|
+
require "active_support/code_generator"
|
10
11
|
require "active_support/core_ext/module/attribute_accessors"
|
11
12
|
require "active_support/core_ext/hash/slice"
|
12
13
|
require "active_support/core_ext/string/output_safety"
|
@@ -212,18 +213,18 @@ module ActionView
|
|
212
213
|
# In the examples above, the object to be created or edited was
|
213
214
|
# represented by a symbol passed to +form_for+, and we noted that
|
214
215
|
# a string can also be used equivalently. It is also possible, however,
|
215
|
-
# to pass a model object itself to +form_for+. For example, if <tt>@
|
216
|
+
# to pass a model object itself to +form_for+. For example, if <tt>@article</tt>
|
216
217
|
# is an existing record you wish to edit, you can create the form using
|
217
218
|
#
|
218
|
-
# <%= form_for @
|
219
|
+
# <%= form_for @article do |f| %>
|
219
220
|
# ...
|
220
221
|
# <% end %>
|
221
222
|
#
|
222
223
|
# This behaves in almost the same way as outlined previously, with a
|
223
224
|
# couple of small exceptions. First, the prefix used to name the input
|
224
225
|
# elements within the form (hence the key that denotes them in the +params+
|
225
|
-
# hash) is actually derived from the object's _class_, e.g. <tt>params[:
|
226
|
-
# if the object's class is +
|
226
|
+
# hash) is actually derived from the object's _class_, e.g. <tt>params[:article]</tt>
|
227
|
+
# if the object's class is +Article+. However, this can be overwritten using
|
227
228
|
# the <tt>:as</tt> option, e.g. -
|
228
229
|
#
|
229
230
|
# <%= form_for(@person, as: :client) do |f| %>
|
@@ -235,15 +236,15 @@ module ActionView
|
|
235
236
|
# Secondly, the field values shown when the form is initially displayed
|
236
237
|
# are taken from the attributes of the object passed to +form_for+,
|
237
238
|
# regardless of whether the object is an instance
|
238
|
-
# variable. So, for example, if we had a _local_ variable +
|
239
|
+
# variable. So, for example, if we had a _local_ variable +article+
|
239
240
|
# representing an existing record,
|
240
241
|
#
|
241
|
-
# <%= form_for
|
242
|
+
# <%= form_for article do |f| %>
|
242
243
|
# ...
|
243
244
|
# <% end %>
|
244
245
|
#
|
245
246
|
# would produce a form with fields whose initial state reflect the current
|
246
|
-
# values of the attributes of +
|
247
|
+
# values of the attributes of +article+.
|
247
248
|
#
|
248
249
|
# === Resource-oriented style
|
249
250
|
#
|
@@ -255,49 +256,49 @@ module ActionView
|
|
255
256
|
# in <tt>config/routes.rb</tt>. In this case \Rails will simply infer the
|
256
257
|
# appropriate URL from the record itself. For example,
|
257
258
|
#
|
258
|
-
# <%= form_for @
|
259
|
+
# <%= form_for @article do |f| %>
|
259
260
|
# ...
|
260
261
|
# <% end %>
|
261
262
|
#
|
262
263
|
# is then equivalent to something like:
|
263
264
|
#
|
264
|
-
# <%= form_for @
|
265
|
+
# <%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
|
265
266
|
# ...
|
266
267
|
# <% end %>
|
267
268
|
#
|
268
269
|
# And for a new record
|
269
270
|
#
|
270
|
-
# <%= form_for(
|
271
|
+
# <%= form_for(Article.new) do |f| %>
|
271
272
|
# ...
|
272
273
|
# <% end %>
|
273
274
|
#
|
274
275
|
# is equivalent to something like:
|
275
276
|
#
|
276
|
-
# <%= form_for @
|
277
|
+
# <%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
|
277
278
|
# ...
|
278
279
|
# <% end %>
|
279
280
|
#
|
280
281
|
# However you can still overwrite individual conventions, such as:
|
281
282
|
#
|
282
|
-
# <%= form_for(@
|
283
|
+
# <%= form_for(@article, url: super_articles_path) do |f| %>
|
283
284
|
# ...
|
284
285
|
# <% end %>
|
285
286
|
#
|
286
287
|
# You can omit the <tt>action</tt> attribute by passing <tt>url: false</tt>:
|
287
288
|
#
|
288
|
-
# <%= form_for(@
|
289
|
+
# <%= form_for(@article, url: false) do |f| %>
|
289
290
|
# ...
|
290
291
|
# <% end %>
|
291
292
|
#
|
292
293
|
# You can also set the answer format, like this:
|
293
294
|
#
|
294
|
-
# <%= form_for(@
|
295
|
+
# <%= form_for(@article, format: :json) do |f| %>
|
295
296
|
# ...
|
296
297
|
# <% end %>
|
297
298
|
#
|
298
|
-
# For namespaced routes, like +
|
299
|
+
# For namespaced routes, like +admin_article_url+:
|
299
300
|
#
|
300
|
-
# <%= form_for([:admin, @
|
301
|
+
# <%= form_for([:admin, @article]) do |f| %>
|
301
302
|
# ...
|
302
303
|
# <% end %>
|
303
304
|
#
|
@@ -333,7 +334,7 @@ module ActionView
|
|
333
334
|
#
|
334
335
|
# Example:
|
335
336
|
#
|
336
|
-
# <%= form_for(@
|
337
|
+
# <%= form_for(@article, remote: true) do |f| %>
|
337
338
|
# ...
|
338
339
|
# <% end %>
|
339
340
|
#
|
@@ -349,7 +350,7 @@ module ActionView
|
|
349
350
|
# You can set data attributes directly by passing in a data hash, but all other HTML options must be wrapped in
|
350
351
|
# the HTML key. Example:
|
351
352
|
#
|
352
|
-
# <%= form_for(@
|
353
|
+
# <%= form_for(@article, data: { behavior: "autosave" }, html: { name: "go" }) do |f| %>
|
353
354
|
# ...
|
354
355
|
# <% end %>
|
355
356
|
#
|
@@ -367,12 +368,12 @@ module ActionView
|
|
367
368
|
# Some ORM systems do not use IDs on nested models so in this case you want to be able
|
368
369
|
# to disable the hidden id.
|
369
370
|
#
|
370
|
-
# In the following example the
|
371
|
+
# In the following example the Article model has many Comments stored within it in a NoSQL database,
|
371
372
|
# thus there is no primary key for comments.
|
372
373
|
#
|
373
374
|
# Example:
|
374
375
|
#
|
375
|
-
# <%= form_for(@
|
376
|
+
# <%= form_for(@article) do |f| %>
|
376
377
|
# <%= f.fields_for(:comments, include_id: false) do |cf| %>
|
377
378
|
# ...
|
378
379
|
# <% end %>
|
@@ -436,7 +437,7 @@ module ActionView
|
|
436
437
|
|
437
438
|
case record
|
438
439
|
when String, Symbol
|
439
|
-
model =
|
440
|
+
model = false
|
440
441
|
object_name = record
|
441
442
|
else
|
442
443
|
model = record
|
@@ -484,12 +485,12 @@ module ActionView
|
|
484
485
|
# Creates a form tag based on mixing URLs, scopes, or models.
|
485
486
|
#
|
486
487
|
# # Using just a URL:
|
487
|
-
# <%= form_with url:
|
488
|
+
# <%= form_with url: articles_path do |form| %>
|
488
489
|
# <%= form.text_field :title %>
|
489
490
|
# <% end %>
|
490
491
|
# # =>
|
491
|
-
# <form action="/
|
492
|
-
# <input type="text" name="title"
|
492
|
+
# <form action="/articles" method="post">
|
493
|
+
# <input type="text" name="title" />
|
493
494
|
# </form>
|
494
495
|
#
|
495
496
|
# # With an intentionally empty URL:
|
@@ -498,37 +499,36 @@ module ActionView
|
|
498
499
|
# <% end %>
|
499
500
|
# # =>
|
500
501
|
# <form method="post">
|
501
|
-
# <input type="text" name="title"
|
502
|
+
# <input type="text" name="title" />
|
502
503
|
# </form>
|
503
504
|
#
|
504
505
|
# # Adding a scope prefixes the input field names:
|
505
|
-
# <%= form_with scope: :
|
506
|
+
# <%= form_with scope: :article, url: articles_path do |form| %>
|
506
507
|
# <%= form.text_field :title %>
|
507
508
|
# <% end %>
|
508
509
|
# # =>
|
509
|
-
# <form action="/
|
510
|
-
# <input type="text" name="
|
510
|
+
# <form action="/articles" method="post">
|
511
|
+
# <input type="text" name="article[title]" />
|
511
512
|
# </form>
|
512
513
|
#
|
513
514
|
# # Using a model infers both the URL and scope:
|
514
|
-
# <%= form_with model:
|
515
|
+
# <%= form_with model: Article.new do |form| %>
|
515
516
|
# <%= form.text_field :title %>
|
516
517
|
# <% end %>
|
517
518
|
# # =>
|
518
|
-
# <form action="/
|
519
|
-
# <input type="text" name="
|
519
|
+
# <form action="/articles" method="post">
|
520
|
+
# <input type="text" name="article[title]" />
|
520
521
|
# </form>
|
521
522
|
#
|
522
523
|
# # An existing model makes an update form and fills out field values:
|
523
|
-
# <%= form_with model:
|
524
|
+
# <%= form_with model: Article.first do |form| %>
|
524
525
|
# <%= form.text_field :title %>
|
525
526
|
# <% end %>
|
526
527
|
# # =>
|
527
|
-
# <form action="/
|
528
|
-
# <input type="hidden" name="_method" value="patch"
|
529
|
-
# <input type="text" name="
|
528
|
+
# <form action="/articles/1" method="post">
|
529
|
+
# <input type="hidden" name="_method" value="patch" />
|
530
|
+
# <input type="text" name="article[title]" value="<the title of the article>" />
|
530
531
|
# </form>
|
531
|
-
#
|
532
532
|
# # Though the fields don't have to correspond to model attributes:
|
533
533
|
# <%= form_with model: Cat.new do |form| %>
|
534
534
|
# <%= form.text_field :cats_dont_have_gills %>
|
@@ -536,13 +536,13 @@ module ActionView
|
|
536
536
|
# <% end %>
|
537
537
|
# # =>
|
538
538
|
# <form action="/cats" method="post">
|
539
|
-
# <input type="text" name="cat[cats_dont_have_gills]"
|
540
|
-
# <input type="text" name="cat[but_in_forms_they_can]"
|
539
|
+
# <input type="text" name="cat[cats_dont_have_gills]" />
|
540
|
+
# <input type="text" name="cat[but_in_forms_they_can]" />
|
541
541
|
# </form>
|
542
542
|
#
|
543
543
|
# The parameters in the forms are accessible in controllers according to
|
544
|
-
# their name nesting. So inputs named +title+ and <tt>
|
545
|
-
# accessible as <tt>params[:title]</tt> and <tt>params[:
|
544
|
+
# their name nesting. So inputs named +title+ and <tt>article[title]</tt> are
|
545
|
+
# accessible as <tt>params[:title]</tt> and <tt>params[:article][:title]</tt>
|
546
546
|
# respectively.
|
547
547
|
#
|
548
548
|
# For ease of comparison the examples above left out the submit button,
|
@@ -558,25 +558,25 @@ module ActionView
|
|
558
558
|
#
|
559
559
|
# So when passing such a model record, \Rails infers the URL and method.
|
560
560
|
#
|
561
|
-
# <%= form_with model: @
|
561
|
+
# <%= form_with model: @article do |form| %>
|
562
562
|
# ...
|
563
563
|
# <% end %>
|
564
564
|
#
|
565
565
|
# is then equivalent to something like:
|
566
566
|
#
|
567
|
-
# <%= form_with scope: :
|
567
|
+
# <%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %>
|
568
568
|
# ...
|
569
569
|
# <% end %>
|
570
570
|
#
|
571
571
|
# And for a new record
|
572
572
|
#
|
573
|
-
# <%= form_with model:
|
573
|
+
# <%= form_with model: Article.new do |form| %>
|
574
574
|
# ...
|
575
575
|
# <% end %>
|
576
576
|
#
|
577
577
|
# is equivalent to something like:
|
578
578
|
#
|
579
|
-
# <%= form_with scope: :
|
579
|
+
# <%= form_with scope: :article, url: articles_path do |form| %>
|
580
580
|
# ...
|
581
581
|
# <% end %>
|
582
582
|
#
|
@@ -605,7 +605,7 @@ module ActionView
|
|
605
605
|
# If the model is a new record a create form is generated, if an
|
606
606
|
# existing record, however, an update form is generated.
|
607
607
|
# Pass <tt>:scope</tt> or <tt>:url</tt> to override the defaults.
|
608
|
-
# E.g. turn <tt>params[:
|
608
|
+
# E.g. turn <tt>params[:article]</tt> into <tt>params[:blog]</tt>.
|
609
609
|
# * <tt>:authenticity_token</tt> - Authenticity token to use in the form.
|
610
610
|
# Override with a custom authenticity token or pass <tt>false</tt> to
|
611
611
|
# skip the authenticity token field altogether.
|
@@ -638,14 +638,14 @@ module ActionView
|
|
638
638
|
#
|
639
639
|
# When not passing a block, +form_with+ just generates an opening form tag.
|
640
640
|
#
|
641
|
-
# <%= form_with(model: @
|
642
|
-
# <%= form_with(model: @
|
643
|
-
# <%= form_with(model: @
|
644
|
-
# <%= form_with(model: @
|
641
|
+
# <%= form_with(model: @article, url: super_articles_path) %>
|
642
|
+
# <%= form_with(model: @article, scope: :blog) %>
|
643
|
+
# <%= form_with(model: @article, format: :json) %>
|
644
|
+
# <%= form_with(model: @article, authenticity_token: false) %> # Disables the token.
|
645
645
|
#
|
646
|
-
# For namespaced routes, like +
|
646
|
+
# For namespaced routes, like +admin_article_url+:
|
647
647
|
#
|
648
|
-
# <%= form_with(model: [ :admin, @
|
648
|
+
# <%= form_with(model: [ :admin, @article ]) do |form| %>
|
649
649
|
# ...
|
650
650
|
# <% end %>
|
651
651
|
#
|
@@ -693,13 +693,13 @@ module ActionView
|
|
693
693
|
# You can set data attributes directly in a data hash, but HTML options
|
694
694
|
# besides id and class must be wrapped in an HTML key:
|
695
695
|
#
|
696
|
-
# <%= form_with(model: @
|
696
|
+
# <%= form_with(model: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
|
697
697
|
# ...
|
698
698
|
# <% end %>
|
699
699
|
#
|
700
700
|
# generates
|
701
701
|
#
|
702
|
-
# <form action="/
|
702
|
+
# <form action="/articles/123" method="post" data-behavior="autosave" name="go">
|
703
703
|
# <input name="_method" type="hidden" value="patch" />
|
704
704
|
# ...
|
705
705
|
# </form>
|
@@ -711,10 +711,10 @@ module ActionView
|
|
711
711
|
# Some ORM systems do not use IDs on nested models so in this case you want to be able
|
712
712
|
# to disable the hidden id.
|
713
713
|
#
|
714
|
-
# In the following example the
|
714
|
+
# In the following example the Article model has many Comments stored within it in a NoSQL database,
|
715
715
|
# thus there is no primary key for comments.
|
716
716
|
#
|
717
|
-
# <%= form_with(model: @
|
717
|
+
# <%= form_with(model: @article) do |form| %>
|
718
718
|
# <%= form.fields(:comments, skip_id: true) do |fields| %>
|
719
719
|
# ...
|
720
720
|
# <% end %>
|
@@ -752,7 +752,9 @@ module ActionView
|
|
752
752
|
# def labelled_form_with(**options, &block)
|
753
753
|
# form_with(**options.merge(builder: LabellingFormBuilder), &block)
|
754
754
|
# end
|
755
|
-
def form_with(model:
|
755
|
+
def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
|
756
|
+
ActionView.deprecator.warn("Passing nil to the :model argument is deprecated and will raise in Rails 7.3") if model.nil?
|
757
|
+
|
756
758
|
options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
|
757
759
|
|
758
760
|
if model
|
@@ -781,23 +783,23 @@ module ActionView
|
|
781
783
|
end
|
782
784
|
end
|
783
785
|
|
784
|
-
# Creates a scope around a specific model object like
|
786
|
+
# Creates a scope around a specific model object like form_with, but
|
785
787
|
# doesn't create the form tags themselves. This makes fields_for suitable
|
786
788
|
# for specifying additional model objects in the same form.
|
787
789
|
#
|
788
|
-
# Although the usage and purpose of +fields_for+ is similar to +
|
789
|
-
# its method signature is slightly different. Like +
|
790
|
+
# Although the usage and purpose of +fields_for+ is similar to +form_with+'s,
|
791
|
+
# its method signature is slightly different. Like +form_with+, it yields
|
790
792
|
# a FormBuilder object associated with a particular model object to a block,
|
791
793
|
# and within the block allows methods to be called on the builder to
|
792
794
|
# generate fields associated with the model object. Fields may reflect
|
793
795
|
# a model object in two ways - how they are named (hence how submitted
|
794
796
|
# values appear within the +params+ hash in the controller) and what
|
795
|
-
# default values are shown when the form
|
796
|
-
#
|
797
|
+
# default values are shown when the form fields are first displayed.
|
798
|
+
# In order for both of these features to be specified independently,
|
797
799
|
# both an object name (represented by either a symbol or string) and the
|
798
800
|
# object itself can be passed to the method separately -
|
799
801
|
#
|
800
|
-
# <%=
|
802
|
+
# <%= form_with model: @person do |person_form| %>
|
801
803
|
# First name: <%= person_form.text_field :first_name %>
|
802
804
|
# Last name : <%= person_form.text_field :last_name %>
|
803
805
|
#
|
@@ -878,7 +880,7 @@ module ActionView
|
|
878
880
|
#
|
879
881
|
# This model can now be used with a nested fields_for, like so:
|
880
882
|
#
|
881
|
-
# <%=
|
883
|
+
# <%= form_with model: @person do |person_form| %>
|
882
884
|
# ...
|
883
885
|
# <%= person_form.fields_for :address do |address_fields| %>
|
884
886
|
# Street : <%= address_fields.text_field :street %>
|
@@ -908,7 +910,7 @@ module ActionView
|
|
908
910
|
# with a value that evaluates to +true+, you will destroy the associated
|
909
911
|
# model (e.g. 1, '1', true, or 'true'):
|
910
912
|
#
|
911
|
-
# <%=
|
913
|
+
# <%= form_with model: @person do |person_form| %>
|
912
914
|
# ...
|
913
915
|
# <%= person_form.fields_for :address do |address_fields| %>
|
914
916
|
# ...
|
@@ -949,7 +951,7 @@ module ActionView
|
|
949
951
|
# the nested fields_for call will be repeated for each instance in the
|
950
952
|
# collection:
|
951
953
|
#
|
952
|
-
# <%=
|
954
|
+
# <%= form_with model: @person do |person_form| %>
|
953
955
|
# ...
|
954
956
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
955
957
|
# <% if project_fields.object.active? %>
|
@@ -961,7 +963,7 @@ module ActionView
|
|
961
963
|
#
|
962
964
|
# It's also possible to specify the instance to be used:
|
963
965
|
#
|
964
|
-
# <%=
|
966
|
+
# <%= form_with model: @person do |person_form| %>
|
965
967
|
# ...
|
966
968
|
# <% @person.projects.each do |project| %>
|
967
969
|
# <% if project.active? %>
|
@@ -975,7 +977,7 @@ module ActionView
|
|
975
977
|
#
|
976
978
|
# Or a collection to be used:
|
977
979
|
#
|
978
|
-
# <%=
|
980
|
+
# <%= form_with model: @person do |person_form| %>
|
979
981
|
# ...
|
980
982
|
# <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
|
981
983
|
# Name: <%= project_fields.text_field :name %>
|
@@ -997,7 +999,7 @@ module ActionView
|
|
997
999
|
# parameter with a value that evaluates to +true+
|
998
1000
|
# (e.g. 1, '1', true, or 'true'):
|
999
1001
|
#
|
1000
|
-
# <%=
|
1002
|
+
# <%= form_with model: @person do |person_form| %>
|
1001
1003
|
# ...
|
1002
1004
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
1003
1005
|
# Delete: <%= project_fields.check_box :_destroy %>
|
@@ -1009,7 +1011,7 @@ module ActionView
|
|
1009
1011
|
# object in the array. For this purpose, the <tt>index</tt> method is
|
1010
1012
|
# available in the FormBuilder object.
|
1011
1013
|
#
|
1012
|
-
# <%=
|
1014
|
+
# <%= form_with model: @person do |person_form| %>
|
1013
1015
|
# ...
|
1014
1016
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
1015
1017
|
# Project #<%= project_fields.index %>
|
@@ -1046,7 +1048,7 @@ module ActionView
|
|
1046
1048
|
# # => <input type="text" name="comment[body]" value="full bodied">
|
1047
1049
|
#
|
1048
1050
|
# # Using +fields+ with +form_with+:
|
1049
|
-
# <%= form_with model: @
|
1051
|
+
# <%= form_with model: @article do |form| %>
|
1050
1052
|
# <%= form.text_field :title %>
|
1051
1053
|
#
|
1052
1054
|
# <%= form.fields :comment do |fields| %>
|
@@ -1094,58 +1096,58 @@ module ActionView
|
|
1094
1096
|
# target labels for radio_button tags (where the value is used in the ID of the input tag).
|
1095
1097
|
#
|
1096
1098
|
# ==== Examples
|
1097
|
-
# label(:
|
1098
|
-
# # => <label for="
|
1099
|
+
# label(:article, :title)
|
1100
|
+
# # => <label for="article_title">Title</label>
|
1099
1101
|
#
|
1100
1102
|
# You can localize your labels based on model and attribute names.
|
1101
1103
|
# For example you can define the following in your locale (e.g. en.yml)
|
1102
1104
|
#
|
1103
1105
|
# helpers:
|
1104
1106
|
# label:
|
1105
|
-
#
|
1107
|
+
# article:
|
1106
1108
|
# body: "Write your entire text here"
|
1107
1109
|
#
|
1108
1110
|
# Which then will result in
|
1109
1111
|
#
|
1110
|
-
# label(:
|
1111
|
-
# # => <label for="
|
1112
|
+
# label(:article, :body)
|
1113
|
+
# # => <label for="article_body">Write your entire text here</label>
|
1112
1114
|
#
|
1113
1115
|
# Localization can also be based purely on the translation of the attribute-name
|
1114
1116
|
# (if you are using ActiveRecord):
|
1115
1117
|
#
|
1116
1118
|
# activerecord:
|
1117
1119
|
# attributes:
|
1118
|
-
#
|
1120
|
+
# article:
|
1119
1121
|
# cost: "Total cost"
|
1120
1122
|
#
|
1121
1123
|
# <code></code>
|
1122
1124
|
#
|
1123
|
-
# label(:
|
1124
|
-
# # => <label for="
|
1125
|
+
# label(:article, :cost)
|
1126
|
+
# # => <label for="article_cost">Total cost</label>
|
1125
1127
|
#
|
1126
|
-
# label(:
|
1127
|
-
# # => <label for="
|
1128
|
+
# label(:article, :title, "A short title")
|
1129
|
+
# # => <label for="article_title">A short title</label>
|
1128
1130
|
#
|
1129
|
-
# label(:
|
1130
|
-
# # => <label for="
|
1131
|
+
# label(:article, :title, "A short title", class: "title_label")
|
1132
|
+
# # => <label for="article_title" class="title_label">A short title</label>
|
1131
1133
|
#
|
1132
|
-
# label(:
|
1133
|
-
# # => <label for="
|
1134
|
+
# label(:article, :privacy, "Public Article", value: "public")
|
1135
|
+
# # => <label for="article_privacy_public">Public Article</label>
|
1134
1136
|
#
|
1135
|
-
# label(:
|
1137
|
+
# label(:article, :cost) do |translation|
|
1136
1138
|
# content_tag(:span, translation, class: "cost_label")
|
1137
1139
|
# end
|
1138
|
-
# # => <label for="
|
1140
|
+
# # => <label for="article_cost"><span class="cost_label">Total cost</span></label>
|
1139
1141
|
#
|
1140
|
-
# label(:
|
1142
|
+
# label(:article, :cost) do |builder|
|
1141
1143
|
# content_tag(:span, builder.translation, class: "cost_label")
|
1142
1144
|
# end
|
1143
|
-
# # => <label for="
|
1145
|
+
# # => <label for="article_cost"><span class="cost_label">Total cost</span></label>
|
1144
1146
|
#
|
1145
|
-
# label(:
|
1147
|
+
# label(:article, :terms) do
|
1146
1148
|
# raw('Accept <a href="/terms">Terms</a>.')
|
1147
1149
|
# end
|
1148
|
-
# # => <label for="
|
1150
|
+
# # => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
|
1149
1151
|
def label(object_name, method, content_or_options = nil, options = nil, &block)
|
1150
1152
|
Tags::Label.new(object_name, method, self, content_or_options, options).render(&block)
|
1151
1153
|
end
|
@@ -1156,14 +1158,14 @@ module ActionView
|
|
1156
1158
|
# shown.
|
1157
1159
|
#
|
1158
1160
|
# ==== Examples
|
1159
|
-
# text_field(:
|
1160
|
-
# # => <input type="text" id="
|
1161
|
+
# text_field(:article, :title, size: 20)
|
1162
|
+
# # => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" />
|
1161
1163
|
#
|
1162
|
-
# text_field(:
|
1163
|
-
# # => <input type="text" id="
|
1164
|
+
# text_field(:article, :title, class: "create_input")
|
1165
|
+
# # => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" />
|
1164
1166
|
#
|
1165
|
-
# text_field(:
|
1166
|
-
# # => <input type="text" id="
|
1167
|
+
# text_field(:article, :title, maxlength: 30, class: "title_input")
|
1168
|
+
# # => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_input" />
|
1167
1169
|
#
|
1168
1170
|
# text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
|
1169
1171
|
# # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
|
@@ -1204,8 +1206,8 @@ module ActionView
|
|
1204
1206
|
# hidden_field(:signup, :pass_confirm)
|
1205
1207
|
# # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
|
1206
1208
|
#
|
1207
|
-
# hidden_field(:
|
1208
|
-
# # => <input type="hidden" id="
|
1209
|
+
# hidden_field(:article, :tag_list)
|
1210
|
+
# # => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" />
|
1209
1211
|
#
|
1210
1212
|
# hidden_field(:user, :token)
|
1211
1213
|
# # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
|
@@ -1218,7 +1220,7 @@ module ActionView
|
|
1218
1220
|
# hash with +options+. These options will be tagged onto the HTML as an HTML element attribute as in the example
|
1219
1221
|
# shown.
|
1220
1222
|
#
|
1221
|
-
# Using this method inside a +
|
1223
|
+
# Using this method inside a +form_with+ block will set the enclosing form's encoding to <tt>multipart/form-data</tt>.
|
1222
1224
|
#
|
1223
1225
|
# ==== Options
|
1224
1226
|
# * Creates standard HTML attributes for the tag.
|
@@ -1231,14 +1233,14 @@ module ActionView
|
|
1231
1233
|
# file_field(:user, :avatar)
|
1232
1234
|
# # => <input type="file" id="user_avatar" name="user[avatar]" />
|
1233
1235
|
#
|
1234
|
-
# file_field(:
|
1235
|
-
# # => <input type="file" id="
|
1236
|
+
# file_field(:article, :image, multiple: true)
|
1237
|
+
# # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" />
|
1236
1238
|
#
|
1237
|
-
# file_field(:
|
1238
|
-
# # => <input accept="text/html" type="file" id="
|
1239
|
+
# file_field(:article, :attached, accept: 'text/html')
|
1240
|
+
# # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" />
|
1239
1241
|
#
|
1240
|
-
# file_field(:
|
1241
|
-
# # => <input type="file" id="
|
1242
|
+
# file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg')
|
1243
|
+
# # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" />
|
1242
1244
|
#
|
1243
1245
|
# file_field(:attachment, :file, class: 'file_input')
|
1244
1246
|
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
|
@@ -1253,9 +1255,9 @@ module ActionView
|
|
1253
1255
|
# hash with +options+.
|
1254
1256
|
#
|
1255
1257
|
# ==== Examples
|
1256
|
-
# text_area(:
|
1257
|
-
# # => <textarea cols="20" rows="40" id="
|
1258
|
-
# # #{@
|
1258
|
+
# text_area(:article, :body, cols: 20, rows: 40)
|
1259
|
+
# # => <textarea cols="20" rows="40" id="article_body" name="article[body]">
|
1260
|
+
# # #{@article.body}
|
1259
1261
|
# # </textarea>
|
1260
1262
|
#
|
1261
1263
|
# text_area(:comment, :text, size: "20x30")
|
@@ -1327,10 +1329,10 @@ module ActionView
|
|
1327
1329
|
#
|
1328
1330
|
# ==== Examples
|
1329
1331
|
#
|
1330
|
-
# # Let's say that @
|
1331
|
-
# check_box("
|
1332
|
-
# # => <input name="
|
1333
|
-
# # <input checked="checked" type="checkbox" id="
|
1332
|
+
# # Let's say that @article.validated? is 1:
|
1333
|
+
# check_box("article", "validated")
|
1334
|
+
# # => <input name="article[validated]" type="hidden" value="0" />
|
1335
|
+
# # <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" />
|
1334
1336
|
#
|
1335
1337
|
# # Let's say that @puppy.gooddog is "no":
|
1336
1338
|
# check_box("puppy", "gooddog", {}, "yes", "no")
|
@@ -1351,11 +1353,11 @@ module ActionView
|
|
1351
1353
|
# To force the radio button to be checked pass <tt>checked: true</tt> in the
|
1352
1354
|
# +options+ hash. You may pass HTML options there as well.
|
1353
1355
|
#
|
1354
|
-
# # Let's say that @
|
1355
|
-
# radio_button("
|
1356
|
-
# radio_button("
|
1357
|
-
# # => <input type="radio" id="
|
1358
|
-
# # <input type="radio" id="
|
1356
|
+
# # Let's say that @article.category returns "rails":
|
1357
|
+
# radio_button("article", "category", "rails")
|
1358
|
+
# radio_button("article", "category", "java")
|
1359
|
+
# # => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
|
1360
|
+
# # <input type="radio" id="article_category_java" name="article[category]" value="java" />
|
1359
1361
|
#
|
1360
1362
|
# # Let's say that @user.receive_newsletter returns "no":
|
1361
1363
|
# radio_button("user", "receive_newsletter", "yes")
|
@@ -1627,10 +1629,10 @@ module ActionView
|
|
1627
1629
|
#
|
1628
1630
|
# A +FormBuilder+ object is associated with a particular model object and
|
1629
1631
|
# allows you to generate fields associated with the model object. The
|
1630
|
-
# +FormBuilder+ object is yielded when using +
|
1632
|
+
# +FormBuilder+ object is yielded when using +form_with+ or +fields_for+.
|
1631
1633
|
# For example:
|
1632
1634
|
#
|
1633
|
-
# <%=
|
1635
|
+
# <%= form_with model: @person do |person_form| %>
|
1634
1636
|
# Name: <%= person_form.text_field :name %>
|
1635
1637
|
# Admin: <%= person_form.check_box :admin %>
|
1636
1638
|
# <% end %>
|
@@ -1666,7 +1668,7 @@ module ActionView
|
|
1666
1668
|
#
|
1667
1669
|
# The +div_radio_button+ code from above can now be used as follows:
|
1668
1670
|
#
|
1669
|
-
# <%=
|
1671
|
+
# <%= form_with model: @person, :builder => MyFormBuilder do |f| %>
|
1670
1672
|
# I am a child: <%= f.div_radio_button(:admin, "child") %>
|
1671
1673
|
# I am an adult: <%= f.div_radio_button(:admin, "adult") %>
|
1672
1674
|
# <% end -%>
|
@@ -1736,7 +1738,7 @@ module ActionView
|
|
1736
1738
|
#
|
1737
1739
|
# return the <tt><form></tt> element's <tt>id</tt> attribute.
|
1738
1740
|
#
|
1739
|
-
# <%=
|
1741
|
+
# <%= form_with model: @article do |f| %>
|
1740
1742
|
# <%# ... %>
|
1741
1743
|
#
|
1742
1744
|
# <% content_for :sticky_footer do %>
|
@@ -1758,7 +1760,7 @@ module ActionView
|
|
1758
1760
|
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
1759
1761
|
# attribute name.
|
1760
1762
|
#
|
1761
|
-
# <%=
|
1763
|
+
# <%= form_with model: @article do |f| %>
|
1762
1764
|
# <%= f.label :title %>
|
1763
1765
|
# <%= f.text_field :title, aria: { describedby: f.field_id(:title, :error) } %>
|
1764
1766
|
# <%= tag.span("is blank", id: f.field_id(:title, :error) %>
|
@@ -1767,7 +1769,7 @@ module ActionView
|
|
1767
1769
|
# In the example above, the <tt><input type="text"></tt> element built by
|
1768
1770
|
# the call to <tt>FormBuilder#text_field</tt> declares an
|
1769
1771
|
# <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
|
1770
|
-
# element, sharing a common <tt>id</tt> root (<tt>
|
1772
|
+
# element, sharing a common <tt>id</tt> root (<tt>article_title</tt>, in this
|
1771
1773
|
# case).
|
1772
1774
|
def field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index])
|
1773
1775
|
@template.field_id(@object_name, method, *suffixes, namespace: namespace, index: index)
|
@@ -1779,14 +1781,14 @@ module ActionView
|
|
1779
1781
|
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
1780
1782
|
# attribute name.
|
1781
1783
|
#
|
1782
|
-
# <%=
|
1784
|
+
# <%= form_with model: @article do |f| %>
|
1783
1785
|
# <%= f.text_field :title, name: f.field_name(:title, :subtitle) %>
|
1784
|
-
# <%# => <input type="text" name="
|
1786
|
+
# <%# => <input type="text" name="article[title][subtitle]"> %>
|
1785
1787
|
# <% end %>
|
1786
1788
|
#
|
1787
|
-
# <%=
|
1789
|
+
# <%= form_with model: @article do |f| %>
|
1788
1790
|
# <%= f.text_field :tag, name: f.field_name(:tag, multiple: true) %>
|
1789
|
-
# <%# => <input type="text" name="
|
1791
|
+
# <%# => <input type="text" name="article[tag][]"> %>
|
1790
1792
|
# <% end %>
|
1791
1793
|
#
|
1792
1794
|
def field_name(method, *methods, multiple: false, index: @options[:index])
|
@@ -2016,35 +2018,39 @@ module ActionView
|
|
2016
2018
|
#
|
2017
2019
|
# Please refer to the documentation of the base helper for details.
|
2018
2020
|
|
2019
|
-
(
|
2020
|
-
|
2021
|
-
|
2022
|
-
|
2023
|
-
#{selector
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2021
|
+
ActiveSupport::CodeGenerator.batch(self, __FILE__, __LINE__) do |code_generator|
|
2022
|
+
(field_helpers - [:label, :check_box, :radio_button, :fields_for, :fields, :hidden_field, :file_field]).each do |selector|
|
2023
|
+
code_generator.define_cached_method(selector, namespace: :form_builder) do |batch|
|
2024
|
+
batch.push <<-RUBY_EVAL
|
2025
|
+
def #{selector}(method, options = {}) # def text_field(method, options = {})
|
2026
|
+
@template.public_send( # @template.public_send(
|
2027
|
+
#{selector.inspect}, # :text_field,
|
2028
|
+
@object_name, # @object_name,
|
2029
|
+
method, # method,
|
2030
|
+
objectify_options(options)) # objectify_options(options))
|
2031
|
+
end # end
|
2032
|
+
RUBY_EVAL
|
2033
|
+
end
|
2034
|
+
end
|
2029
2035
|
end
|
2030
2036
|
|
2031
|
-
# Creates a scope around a specific model object like
|
2037
|
+
# Creates a scope around a specific model object like form_with, but
|
2032
2038
|
# doesn't create the form tags themselves. This makes fields_for suitable
|
2033
2039
|
# for specifying additional model objects in the same form.
|
2034
2040
|
#
|
2035
|
-
# Although the usage and purpose of +fields_for+ is similar to +
|
2036
|
-
# its method signature is slightly different. Like +
|
2041
|
+
# Although the usage and purpose of +fields_for+ is similar to +form_with+'s,
|
2042
|
+
# its method signature is slightly different. Like +form_with+, it yields
|
2037
2043
|
# a FormBuilder object associated with a particular model object to a block,
|
2038
2044
|
# and within the block allows methods to be called on the builder to
|
2039
2045
|
# generate fields associated with the model object. Fields may reflect
|
2040
2046
|
# a model object in two ways - how they are named (hence how submitted
|
2041
2047
|
# values appear within the +params+ hash in the controller) and what
|
2042
|
-
# default values are shown when the form
|
2043
|
-
#
|
2048
|
+
# default values are shown when the form fields are first displayed.
|
2049
|
+
# In order for both of these features to be specified independently,
|
2044
2050
|
# both an object name (represented by either a symbol or string) and the
|
2045
2051
|
# object itself can be passed to the method separately -
|
2046
2052
|
#
|
2047
|
-
# <%=
|
2053
|
+
# <%= form_with model: @person do |person_form| %>
|
2048
2054
|
# First name: <%= person_form.text_field :first_name %>
|
2049
2055
|
# Last name : <%= person_form.text_field :last_name %>
|
2050
2056
|
#
|
@@ -2093,7 +2099,7 @@ module ActionView
|
|
2093
2099
|
# name and value parameters are provided and the provided value has the shape of an
|
2094
2100
|
# option Hash. To remove the ambiguity, explicitly pass an option Hash, even if empty.
|
2095
2101
|
#
|
2096
|
-
# <%=
|
2102
|
+
# <%= form_with model: @person do |person_form| %>
|
2097
2103
|
# ...
|
2098
2104
|
# <%= fields_for :permission, @person.permission, {} do |permission_fields| %>
|
2099
2105
|
# Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
|
@@ -2137,7 +2143,7 @@ module ActionView
|
|
2137
2143
|
#
|
2138
2144
|
# This model can now be used with a nested fields_for, like so:
|
2139
2145
|
#
|
2140
|
-
# <%=
|
2146
|
+
# <%= form_with model: @person do |person_form| %>
|
2141
2147
|
# ...
|
2142
2148
|
# <%= person_form.fields_for :address do |address_fields| %>
|
2143
2149
|
# Street : <%= address_fields.text_field :street %>
|
@@ -2167,7 +2173,7 @@ module ActionView
|
|
2167
2173
|
# with a value that evaluates to +true+, you will destroy the associated
|
2168
2174
|
# model (e.g. 1, '1', true, or 'true'):
|
2169
2175
|
#
|
2170
|
-
# <%=
|
2176
|
+
# <%= form_with model: @person do |person_form| %>
|
2171
2177
|
# ...
|
2172
2178
|
# <%= person_form.fields_for :address do |address_fields| %>
|
2173
2179
|
# ...
|
@@ -2208,7 +2214,7 @@ module ActionView
|
|
2208
2214
|
# the nested fields_for call will be repeated for each instance in the
|
2209
2215
|
# collection:
|
2210
2216
|
#
|
2211
|
-
# <%=
|
2217
|
+
# <%= form_with model: @person do |person_form| %>
|
2212
2218
|
# ...
|
2213
2219
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
2214
2220
|
# <% if project_fields.object.active? %>
|
@@ -2220,7 +2226,7 @@ module ActionView
|
|
2220
2226
|
#
|
2221
2227
|
# It's also possible to specify the instance to be used:
|
2222
2228
|
#
|
2223
|
-
# <%=
|
2229
|
+
# <%= form_with model: @person do |person_form| %>
|
2224
2230
|
# ...
|
2225
2231
|
# <% @person.projects.each do |project| %>
|
2226
2232
|
# <% if project.active? %>
|
@@ -2234,7 +2240,7 @@ module ActionView
|
|
2234
2240
|
#
|
2235
2241
|
# Or a collection to be used:
|
2236
2242
|
#
|
2237
|
-
# <%=
|
2243
|
+
# <%= form_with model: @person do |person_form| %>
|
2238
2244
|
# ...
|
2239
2245
|
# <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
|
2240
2246
|
# Name: <%= project_fields.text_field :name %>
|
@@ -2256,7 +2262,7 @@ module ActionView
|
|
2256
2262
|
# parameter with a value that evaluates to +true+
|
2257
2263
|
# (e.g. 1, '1', true, or 'true'):
|
2258
2264
|
#
|
2259
|
-
# <%=
|
2265
|
+
# <%= form_with model: @person do |person_form| %>
|
2260
2266
|
# ...
|
2261
2267
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
2262
2268
|
# Delete: <%= project_fields.check_box :_destroy %>
|
@@ -2268,7 +2274,7 @@ module ActionView
|
|
2268
2274
|
# object in the array. For this purpose, the <tt>index</tt> method
|
2269
2275
|
# is available in the FormBuilder object.
|
2270
2276
|
#
|
2271
|
-
# <%=
|
2277
|
+
# <%= form_with model: @person do |person_form| %>
|
2272
2278
|
# ...
|
2273
2279
|
# <%= person_form.fields_for :projects do |project_fields| %>
|
2274
2280
|
# Project #<%= project_fields.index %>
|
@@ -2337,52 +2343,52 @@ module ActionView
|
|
2337
2343
|
#
|
2338
2344
|
# ==== Examples
|
2339
2345
|
# label(:title)
|
2340
|
-
# # => <label for="
|
2346
|
+
# # => <label for="article_title">Title</label>
|
2341
2347
|
#
|
2342
2348
|
# You can localize your labels based on model and attribute names.
|
2343
2349
|
# For example you can define the following in your locale (e.g. en.yml)
|
2344
2350
|
#
|
2345
2351
|
# helpers:
|
2346
2352
|
# label:
|
2347
|
-
#
|
2353
|
+
# article:
|
2348
2354
|
# body: "Write your entire text here"
|
2349
2355
|
#
|
2350
2356
|
# Which then will result in
|
2351
2357
|
#
|
2352
2358
|
# label(:body)
|
2353
|
-
# # => <label for="
|
2359
|
+
# # => <label for="article_body">Write your entire text here</label>
|
2354
2360
|
#
|
2355
2361
|
# Localization can also be based purely on the translation of the attribute-name
|
2356
2362
|
# (if you are using ActiveRecord):
|
2357
2363
|
#
|
2358
2364
|
# activerecord:
|
2359
2365
|
# attributes:
|
2360
|
-
#
|
2366
|
+
# article:
|
2361
2367
|
# cost: "Total cost"
|
2362
2368
|
#
|
2363
2369
|
# <code></code>
|
2364
2370
|
#
|
2365
2371
|
# label(:cost)
|
2366
|
-
# # => <label for="
|
2372
|
+
# # => <label for="article_cost">Total cost</label>
|
2367
2373
|
#
|
2368
2374
|
# label(:title, "A short title")
|
2369
|
-
# # => <label for="
|
2375
|
+
# # => <label for="article_title">A short title</label>
|
2370
2376
|
#
|
2371
2377
|
# label(:title, "A short title", class: "title_label")
|
2372
|
-
# # => <label for="
|
2378
|
+
# # => <label for="article_title" class="title_label">A short title</label>
|
2373
2379
|
#
|
2374
|
-
# label(:privacy, "Public
|
2375
|
-
# # => <label for="
|
2380
|
+
# label(:privacy, "Public Article", value: "public")
|
2381
|
+
# # => <label for="article_privacy_public">Public Article</label>
|
2376
2382
|
#
|
2377
2383
|
# label(:cost) do |translation|
|
2378
2384
|
# content_tag(:span, translation, class: "cost_label")
|
2379
2385
|
# end
|
2380
|
-
# # => <label for="
|
2386
|
+
# # => <label for="article_cost"><span class="cost_label">Total cost</span></label>
|
2381
2387
|
#
|
2382
2388
|
# label(:cost) do |builder|
|
2383
2389
|
# content_tag(:span, builder.translation, class: "cost_label")
|
2384
2390
|
# end
|
2385
|
-
# # => <label for="
|
2391
|
+
# # => <label for="article_cost"><span class="cost_label">Total cost</span></label>
|
2386
2392
|
#
|
2387
2393
|
# label(:cost) do |builder|
|
2388
2394
|
# content_tag(:span, builder.translation, class: [
|
@@ -2390,12 +2396,12 @@ module ActionView
|
|
2390
2396
|
# ("error_label" if builder.object.errors.include?(:cost))
|
2391
2397
|
# ])
|
2392
2398
|
# end
|
2393
|
-
# # => <label for="
|
2399
|
+
# # => <label for="article_cost"><span class="cost_label error_label">Total cost</span></label>
|
2394
2400
|
#
|
2395
2401
|
# label(:terms) do
|
2396
2402
|
# raw('Accept <a href="/terms">Terms</a>.')
|
2397
2403
|
# end
|
2398
|
-
# # => <label for="
|
2404
|
+
# # => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
|
2399
2405
|
def label(method, text = nil, options = {}, &block)
|
2400
2406
|
@template.label(@object_name, method, text, objectify_options(options), &block)
|
2401
2407
|
end
|
@@ -2451,10 +2457,10 @@ module ActionView
|
|
2451
2457
|
#
|
2452
2458
|
# ==== Examples
|
2453
2459
|
#
|
2454
|
-
# # Let's say that @
|
2460
|
+
# # Let's say that @article.validated? is 1:
|
2455
2461
|
# check_box("validated")
|
2456
|
-
# # => <input name="
|
2457
|
-
# # <input checked="checked" type="checkbox" id="
|
2462
|
+
# # => <input name="article[validated]" type="hidden" value="0" />
|
2463
|
+
# # <input checked="checked" type="checkbox" id="article_validated" name="article[validated]" value="1" />
|
2458
2464
|
#
|
2459
2465
|
# # Let's say that @puppy.gooddog is "no":
|
2460
2466
|
# check_box("gooddog", {}, "yes", "no")
|
@@ -2476,11 +2482,11 @@ module ActionView
|
|
2476
2482
|
# To force the radio button to be checked pass <tt>checked: true</tt> in the
|
2477
2483
|
# +options+ hash. You may pass HTML options there as well.
|
2478
2484
|
#
|
2479
|
-
# # Let's say that @
|
2485
|
+
# # Let's say that @article.category returns "rails":
|
2480
2486
|
# radio_button("category", "rails")
|
2481
2487
|
# radio_button("category", "java")
|
2482
|
-
# # => <input type="radio" id="
|
2483
|
-
# # <input type="radio" id="
|
2488
|
+
# # => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
|
2489
|
+
# # <input type="radio" id="article_category_java" name="article[category]" value="java" />
|
2484
2490
|
#
|
2485
2491
|
# # Let's say that @user.receive_newsletter returns "no":
|
2486
2492
|
# radio_button("receive_newsletter", "yes")
|
@@ -2501,9 +2507,9 @@ module ActionView
|
|
2501
2507
|
# hidden_field(:pass_confirm)
|
2502
2508
|
# # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="true" />
|
2503
2509
|
#
|
2504
|
-
# # Let's say that @
|
2510
|
+
# # Let's say that @article.tag_list returns "blog, ruby":
|
2505
2511
|
# hidden_field(:tag_list)
|
2506
|
-
# # => <input type="hidden" id="
|
2512
|
+
# # => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="blog, ruby" />
|
2507
2513
|
#
|
2508
2514
|
# # Let's say that @user.token returns "abcde":
|
2509
2515
|
# hidden_field(:token)
|
@@ -2533,17 +2539,17 @@ module ActionView
|
|
2533
2539
|
# file_field(:avatar)
|
2534
2540
|
# # => <input type="file" id="user_avatar" name="user[avatar]" />
|
2535
2541
|
#
|
2536
|
-
# # Let's say that @
|
2542
|
+
# # Let's say that @article has image:
|
2537
2543
|
# file_field(:image, :multiple => true)
|
2538
|
-
# # => <input type="file" id="
|
2544
|
+
# # => <input type="file" id="article_image" name="article[image][]" multiple="multiple" />
|
2539
2545
|
#
|
2540
|
-
# # Let's say that @
|
2546
|
+
# # Let's say that @article has attached:
|
2541
2547
|
# file_field(:attached, accept: 'text/html')
|
2542
|
-
# # => <input accept="text/html" type="file" id="
|
2548
|
+
# # => <input accept="text/html" type="file" id="article_attached" name="article[attached]" />
|
2543
2549
|
#
|
2544
|
-
# # Let's say that @
|
2550
|
+
# # Let's say that @article has image:
|
2545
2551
|
# file_field(:image, accept: 'image/png,image/gif,image/jpeg')
|
2546
|
-
# # => <input type="file" id="
|
2552
|
+
# # => <input type="file" id="article_image" name="article[image]" accept="image/png,image/gif,image/jpeg" />
|
2547
2553
|
#
|
2548
2554
|
# # Let's say that @attachment has file:
|
2549
2555
|
# file_field(:file, class: 'file_input')
|
@@ -2556,12 +2562,12 @@ module ActionView
|
|
2556
2562
|
# Add the submit button for the given form. When no value is given, it checks
|
2557
2563
|
# if the object is a new resource or not to create the proper label:
|
2558
2564
|
#
|
2559
|
-
# <%=
|
2565
|
+
# <%= form_with model: @article do |f| %>
|
2560
2566
|
# <%= f.submit %>
|
2561
2567
|
# <% end %>
|
2562
2568
|
#
|
2563
|
-
# In the example above, if <tt>@
|
2564
|
-
# submit button label; otherwise, it uses "Update
|
2569
|
+
# In the example above, if <tt>@article</tt> is a new record, it will use "Create Article" as
|
2570
|
+
# submit button label; otherwise, it uses "Update Article".
|
2565
2571
|
#
|
2566
2572
|
# Those labels can be customized using I18n under the +helpers.submit+ key and using
|
2567
2573
|
# <tt>%{model}</tt> for translation interpolation:
|
@@ -2577,7 +2583,7 @@ module ActionView
|
|
2577
2583
|
# en:
|
2578
2584
|
# helpers:
|
2579
2585
|
# submit:
|
2580
|
-
#
|
2586
|
+
# article:
|
2581
2587
|
# create: "Add %{model}"
|
2582
2588
|
#
|
2583
2589
|
def submit(value = nil, options = {})
|
@@ -2589,12 +2595,11 @@ module ActionView
|
|
2589
2595
|
# Add the submit button for the given form. When no value is given, it checks
|
2590
2596
|
# if the object is a new resource or not to create the proper label:
|
2591
2597
|
#
|
2592
|
-
# <%=
|
2598
|
+
# <%= form_with model: @article do |f| %>
|
2593
2599
|
# <%= f.button %>
|
2594
2600
|
# <% end %>
|
2595
|
-
#
|
2596
|
-
#
|
2597
|
-
# button label; otherwise, it uses "Update Post".
|
2601
|
+
# In the example above, if <tt>@article</tt> is a new record, it will use "Create Article" as
|
2602
|
+
# button label; otherwise, it uses "Update Article".
|
2598
2603
|
#
|
2599
2604
|
# Those labels can be customized using I18n under the +helpers.submit+ key
|
2600
2605
|
# (the same as submit helper) and using <tt>%{model}</tt> for translation interpolation:
|
@@ -2610,15 +2615,15 @@ module ActionView
|
|
2610
2615
|
# en:
|
2611
2616
|
# helpers:
|
2612
2617
|
# submit:
|
2613
|
-
#
|
2618
|
+
# article:
|
2614
2619
|
# create: "Add %{model}"
|
2615
2620
|
#
|
2616
2621
|
# ==== Examples
|
2617
|
-
# button("Create
|
2618
|
-
# # => <button name='button' type='submit'>Create
|
2622
|
+
# button("Create article")
|
2623
|
+
# # => <button name='button' type='submit'>Create article</button>
|
2619
2624
|
#
|
2620
2625
|
# button(:draft, value: true)
|
2621
|
-
# # => <button id="
|
2626
|
+
# # => <button id="article_draft" name="article[draft]" value="true" type="submit">Create article</button>
|
2622
2627
|
#
|
2623
2628
|
# button do
|
2624
2629
|
# content_tag(:strong, 'Ask me!')
|
@@ -2631,13 +2636,13 @@ module ActionView
|
|
2631
2636
|
# content_tag(:strong, text)
|
2632
2637
|
# end
|
2633
2638
|
# # => <button name='button' type='submit'>
|
2634
|
-
# # <strong>Create
|
2639
|
+
# # <strong>Create article</strong>
|
2635
2640
|
# # </button>
|
2636
2641
|
#
|
2637
2642
|
# button(:draft, value: true) do
|
2638
2643
|
# content_tag(:strong, "Save as draft")
|
2639
2644
|
# end
|
2640
|
-
# # => <button id="
|
2645
|
+
# # => <button id="article_draft" name="article[draft]" value="true" type="submit">
|
2641
2646
|
# # <strong>Save as draft</strong>
|
2642
2647
|
# # </button>
|
2643
2648
|
#
|