mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Introduce field_name
view helper
The `field_name` helper and corresponding `FormBuilder#field_name` method provide an Action View-compliant way of overriding a form field element's `[name]` attribute (similar to `field_id` and `FormBuilder#field_id` introduced in rails/rails#40127[][]). ```ruby text_field_tag :post, :title, name: field_name(:post, :title, :subtitle) # => <input type="text" name="post[title][subtitle]"> text_field_tag :post, :tag, name: field_name(:post, :tag, multiple: true) # => <input type="text" name="post[tag][]"> form_for @post do |f| f.field_tag :tag, name: f.field_name(:tag, multiple: true) # => <input type="text" name="post[tag][]"> end ``` [rails/rails#40127]: https://github.com/rails/rails/pull/40127
This commit is contained in:
parent
9f980664fc
commit
37081bf507
6 changed files with 241 additions and 9 deletions
|
@ -1,3 +1,15 @@
|
|||
* Introduce the `field_name` view helper, along with the
|
||||
`FormBuilder#field_name` counterpart:
|
||||
|
||||
```ruby
|
||||
form_for @post do |f|
|
||||
f.field_tag :tag, name: f.field_name(:tag, multiple: true)
|
||||
# => <input type="text" name="post[tag][]">
|
||||
end
|
||||
```
|
||||
|
||||
*Sean Doyle*
|
||||
|
||||
* Add `:day_format` option to `date_select`
|
||||
|
||||
date_select("article", "written_on", day_format: ->(day) { day.ordinalize })
|
||||
|
|
|
@ -1746,6 +1746,28 @@ module ActionView
|
|||
@template.field_id(@object_name, method, *suffixes, index: index)
|
||||
end
|
||||
|
||||
# Generate an HTML <tt>name</tt> attribute value for the given name and
|
||||
# field combination
|
||||
#
|
||||
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
||||
# attribute name.
|
||||
#
|
||||
# <%= form_for @post do |f| %>
|
||||
# <%= f.text_field :title, name: f.field_name(:title, :subtitle) %>
|
||||
# <%# => <input type="text" name="post[title][subtitle]">
|
||||
# <% end %>
|
||||
#
|
||||
# <%= form_for @post do |f| %>
|
||||
# <%= f.field_tag :tag, name: f.field_name(:tag, multiple: true) %>
|
||||
# <%# => <input type="text" name="post[tag][]">
|
||||
# <% end %>
|
||||
#
|
||||
def field_name(method, *methods, multiple: false, index: @index)
|
||||
object_name = @options.fetch(:as) { @object_name }
|
||||
|
||||
@template.field_name(object_name, method, *methods, index: index, multiple: multiple)
|
||||
end
|
||||
|
||||
##
|
||||
# :method: text_field
|
||||
#
|
||||
|
|
|
@ -114,6 +114,32 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
# Generate an HTML <tt>name</tt> attribute value for the given name and
|
||||
# field combination
|
||||
#
|
||||
# Return the value generated by the <tt>FormBuilder</tt> for the given
|
||||
# attribute name.
|
||||
#
|
||||
# <%= text_field_tag :post, :title, name: field_name(:post, :title, :subtitle) %>
|
||||
# <%# => <input type="text" name="post[title][subtitle]">
|
||||
#
|
||||
# <%= text_field_tag :post, :tag, name: field_name(:post, :tag, multiple: true) %>
|
||||
# <%# => <input type="text" name="post[tag][]">
|
||||
#
|
||||
def field_name(object_name, method_name, *method_names, multiple: false, index: nil)
|
||||
names = method_names.map! { |name| "[#{name}]" }.join
|
||||
|
||||
# a little duplication to construct fewer strings
|
||||
case
|
||||
when object_name.empty?
|
||||
"#{method_name}#{names}#{multiple ? "[]" : ""}"
|
||||
when index
|
||||
"#{object_name}[#{index}][#{method_name}]#{names}#{multiple ? "[]" : ""}"
|
||||
else
|
||||
"#{object_name}[#{method_name}]#{names}#{multiple ? "[]" : ""}"
|
||||
end
|
||||
end
|
||||
|
||||
# Creates a dropdown selection box, or if the <tt>:multiple</tt> option is set to true, a multiple
|
||||
# choice selection box.
|
||||
#
|
||||
|
|
|
@ -105,15 +105,7 @@ module ActionView
|
|||
end
|
||||
|
||||
def tag_name(multiple = false, index = nil)
|
||||
# a little duplication to construct fewer strings
|
||||
case
|
||||
when @object_name.empty?
|
||||
"#{sanitized_method_name}#{multiple ? "[]" : ""}"
|
||||
when index
|
||||
"#{@object_name}[#{index}][#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
||||
else
|
||||
"#{@object_name}[#{sanitized_method_name}]#{multiple ? "[]" : ""}"
|
||||
end
|
||||
@template_object.field_name(@object_name, sanitized_method_name, multiple: multiple, index: index)
|
||||
end
|
||||
|
||||
def tag_id(index = nil)
|
||||
|
|
|
@ -1659,6 +1659,126 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_blank_as
|
||||
form_for(Post.new, as: "") do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_", "new_") do
|
||||
%(<input id="title" name="title" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_blank_as_and_multiple
|
||||
form_for(Post.new, as: "") do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, multiple: true))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_", "new_") do
|
||||
%(<input id="title" name="title[]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_without_method_names_or_multiple_or_index
|
||||
form_for(Post.new) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_title" name="post[title]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_without_method_names_and_multiple
|
||||
form_for(Post.new) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, multiple: true))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_title" name="post[title][]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_without_method_names_and_index
|
||||
form_for(Post.new, index: 1) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_1_title" name="post[1][title]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_without_method_names_and_index_and_multiple
|
||||
form_for(Post.new, index: 1) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, multiple: true))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_1_title" name="post[1][title][]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_method_names
|
||||
form_for(Post.new) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, :subtitle))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_title" name="post[title][subtitle]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_method_names_and_index
|
||||
form_for(Post.new, index: 1) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, :subtitle))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_1_title" name="post[1][title][subtitle]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_method_names_and_multiple
|
||||
form_for(Post.new) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, :subtitle, multiple: true))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_title" name="post[title][subtitle][]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_field_name_with_method_names_and_multiple_and_index
|
||||
form_for(Post.new, index: 1) do |form|
|
||||
concat form.text_field(:title, name: form.field_name(:title, :subtitle, multiple: true))
|
||||
end
|
||||
|
||||
expected = whole_form("/posts", "new_post", "new_post") do
|
||||
%(<input id="post_1_title" name="post[1][title][subtitle][]" type="text">)
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_collection_radio_buttons
|
||||
post = Post.new
|
||||
def post.active; false; end
|
||||
|
|
|
@ -211,6 +211,66 @@ class FormTagHelperTest < ActionView::TestCase
|
|||
assert_equal "post_author_name", value
|
||||
end
|
||||
|
||||
def test_field_name_without_object_name
|
||||
value = field_name("", :title)
|
||||
|
||||
assert_equal "title", value
|
||||
end
|
||||
|
||||
def test_field_name_without_object_name_and_multiple
|
||||
value = field_name("", :title, multiple: true)
|
||||
|
||||
assert_equal "title[]", value
|
||||
end
|
||||
|
||||
def test_field_name_without_method_names_or_multiple_or_index
|
||||
value = field_name(:post, :title)
|
||||
|
||||
assert_equal "post[title]", value
|
||||
end
|
||||
|
||||
def test_field_name_without_method_names_and_multiple
|
||||
value = field_name(:post, :title, multiple: true)
|
||||
|
||||
assert_equal "post[title][]", value
|
||||
end
|
||||
|
||||
def test_field_name_without_method_names_and_index
|
||||
value = field_name(:post, :title, index: 1)
|
||||
|
||||
assert_equal "post[1][title]", value
|
||||
end
|
||||
|
||||
def test_field_name_without_method_names_and_index_and_multiple
|
||||
value = field_name(:post, :title, index: 1, multiple: true)
|
||||
|
||||
assert_equal "post[1][title][]", value
|
||||
end
|
||||
|
||||
def test_field_name_with_method_names
|
||||
value = field_name(:post, :title, :subtitle)
|
||||
|
||||
assert_equal "post[title][subtitle]", value
|
||||
end
|
||||
|
||||
def test_field_name_with_method_names_and_index
|
||||
value = field_name(:post, :title, :subtitle, index: 1)
|
||||
|
||||
assert_equal "post[1][title][subtitle]", value
|
||||
end
|
||||
|
||||
def test_field_name_with_method_names_and_multiple
|
||||
value = field_name(:post, :title, :subtitle, multiple: true)
|
||||
|
||||
assert_equal "post[title][subtitle][]", value
|
||||
end
|
||||
|
||||
def test_field_name_with_method_names_and_multiple_and_index
|
||||
value = field_name(:post, :title, :subtitle, index: 1, multiple: true)
|
||||
|
||||
assert_equal "post[1][title][subtitle][]", value
|
||||
end
|
||||
|
||||
def test_hidden_field_tag
|
||||
actual = hidden_field_tag "id", 3
|
||||
expected = %(<input id="id" name="id" type="hidden" value="3" autocomplete="off" />)
|
||||
|
|
Loading…
Reference in a new issue