Merge pull request #17973 from maurogeorge/file_field_hidden_field
Generate a hidden_tag when using a file_field
This commit is contained in:
commit
c455817804
@ -1,6 +1,12 @@
|
||||
* Add a `hidden_field` on the `file_field` to avoid raise a error when the only
|
||||
input on the form is the `file_field`.
|
||||
|
||||
*Mauro George*
|
||||
|
||||
* Add an explicit error message, in `ActionView::PartialRenderer` for partial
|
||||
`rendering`, when the value of option `as` has invalid characters.
|
||||
|
||||
*Angelo Capilleri*
|
||||
|
||||
|
||||
Please check [4-2-stable](https://github.com/rails/rails/blob/4-2-stable/actionview/CHANGELOG.md) for previous changes.
|
||||
|
@ -854,6 +854,23 @@ def hidden_field(object_name, method, options = {})
|
||||
#
|
||||
# file_field(:attachment, :file, class: 'file_input')
|
||||
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
|
||||
#
|
||||
# ==== Gotcha
|
||||
#
|
||||
# The HTML specification says when nothing is select on a file field web browsers do not send any value to server.
|
||||
# Unfortunately this introduces a gotcha:
|
||||
# if an +User+ model has a +avatar+ field, and in the form none file is selected no +avatar+ parameter is sent. So,
|
||||
# any mass-assignment idiom like
|
||||
#
|
||||
# @user.update(params[:user])
|
||||
#
|
||||
# wouldn't update avatar.
|
||||
#
|
||||
# To prevent this the helper generates an auxiliary hidden field before
|
||||
# every file field. The hidden field has the same name as file field and blank value.
|
||||
#
|
||||
# In case if you don't want the helper to generate this hidden field you can specify
|
||||
# <tt>include_hidden: false</tt> option.
|
||||
def file_field(object_name, method, options = {})
|
||||
Tags::FileField.new(object_name, method, self, options).render
|
||||
end
|
||||
|
@ -2,6 +2,21 @@ module ActionView
|
||||
module Helpers
|
||||
module Tags # :nodoc:
|
||||
class FileField < TextField # :nodoc:
|
||||
|
||||
def render
|
||||
options = @options.stringify_keys
|
||||
|
||||
if options.fetch("include_hidden", true)
|
||||
add_default_name_and_id(options)
|
||||
options[:type] = "file"
|
||||
tag("input", name: options["name"], type: "hidden", value: "") + tag("input", options)
|
||||
else
|
||||
options.delete("include_hidden")
|
||||
@options = options
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -472,18 +472,33 @@ def test_text_field_doesnt_change_param_values
|
||||
assert_dom_equal expected, text_field(object_name, "title")
|
||||
end
|
||||
|
||||
def test_file_field_has_no_size
|
||||
def test_file_field_does_generate_a_hidden_field
|
||||
expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
|
||||
assert_dom_equal expected, file_field("user", "avatar")
|
||||
end
|
||||
|
||||
def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false
|
||||
expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
|
||||
assert_dom_equal expected, file_field("user", "avatar", include_hidden: false)
|
||||
end
|
||||
|
||||
def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false_with_key_as_string
|
||||
expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
|
||||
assert_dom_equal expected, file_field("user", "avatar", "include_hidden" => false)
|
||||
end
|
||||
|
||||
def test_file_field_has_no_size
|
||||
expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
|
||||
assert_dom_equal expected, file_field("user", "avatar")
|
||||
end
|
||||
|
||||
def test_file_field_with_multiple_behavior
|
||||
expected = '<input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
|
||||
expected = '<input name="import[file][]" type="hidden" value="" /><input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
|
||||
assert_dom_equal expected, file_field("import", "file", :multiple => true)
|
||||
end
|
||||
|
||||
def test_file_field_with_multiple_behavior_and_explicit_name
|
||||
expected = '<input id="import_file" multiple="multiple" name="custom" type="file" />'
|
||||
expected = '<input name="custom" type="hidden" value="" /><input id="import_file" multiple="multiple" name="custom" type="file" />'
|
||||
assert_dom_equal expected, file_field("import", "file", :multiple => true, :name => "custom")
|
||||
end
|
||||
|
||||
@ -1719,7 +1734,7 @@ def test_form_for_with_file_field_generate_multipart
|
||||
end
|
||||
|
||||
expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch", multipart: true) do
|
||||
"<input name='post[file]' type='file' id='post_file' />"
|
||||
"<input name='post[file]' type='hidden' value='' /><input name='post[file]' type='file' id='post_file' />"
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
@ -1735,7 +1750,7 @@ def test_fields_for_with_file_field_generate_multipart
|
||||
end
|
||||
|
||||
expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch", multipart: true) do
|
||||
"<input name='post[comment][file]' type='file' id='post_comment_file' />"
|
||||
"<input name='post[comment][file]' type='hidden' value='' /><input name='post[comment][file]' type='file' id='post_comment_file' />"
|
||||
end
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
|
Loading…
Reference in New Issue
Block a user