Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement field_id in terms of the FormBuilder's namespace: option #43408

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions actionview/lib/action_view/helpers/form_helper.rb
Expand Up @@ -1748,8 +1748,8 @@ def id
# <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
# element, sharing a common <tt>id</tt> root (<tt>post_title</tt>, in this
# case).
def field_id(method, *suffixes, index: @index)
@template.field_id(@object_name, method, *suffixes, index: index)
def field_id(method, *suffixes, namespace: @options[:namespace], index: @index)
@template.field_id(@object_name, method, *suffixes, namespace: namespace, index: index)
end

# Generate an HTML <tt>name</tt> attribute value for the given name and
Expand Down
19 changes: 8 additions & 11 deletions actionview/lib/action_view/helpers/form_tag_helper.rb
Expand Up @@ -96,7 +96,7 @@ def form_tag(url_for_options = {}, options = {}, &block)
# <tt>aria-describedby</tt> attribute referencing the <tt><span></tt>
# element, sharing a common <tt>id</tt> root (<tt>post_title</tt>, in this
# case).
def field_id(object_name, method_name, *suffixes, index: nil)
def field_id(object_name, method_name, *suffixes, index: nil, namespace: nil)
if object_name.respond_to?(:model_name)
object_name = object_name.model_name.singular
end
Expand All @@ -105,16 +105,13 @@ def field_id(object_name, method_name, *suffixes, index: nil)

sanitized_method_name = method_name.to_s.delete_suffix("?")

# a little duplication to construct fewer strings
if sanitized_object_name.empty?
sanitized_method_name
elsif suffixes.any?
[sanitized_object_name, index, sanitized_method_name, *suffixes].compact.join("_")
elsif index
"#{sanitized_object_name}_#{index}_#{sanitized_method_name}"
else
"#{sanitized_object_name}_#{sanitized_method_name}"
end
[
namespace,
sanitized_object_name.presence,
(index unless sanitized_object_name.empty?),
sanitized_method_name,
*suffixes,
].tap(&:compact!).join("_")
end

# Generate an HTML <tt>name</tt> attribute value for the given name and
Expand Down
6 changes: 3 additions & 3 deletions actionview/lib/action_view/helpers/tags/base.rb
Expand Up @@ -97,7 +97,7 @@ def add_default_name_and_id(options)
options["name"] = options.fetch("name") { tag_name(options["multiple"], index) }

if generate_ids?
options["id"] = options.fetch("id") { tag_id(index) }
options["id"] = options.fetch("id") { tag_id(index, options.delete("namespace")) }
if namespace = options.delete("namespace")
options["id"] = options["id"] ? "#{namespace}_#{options['id']}" : namespace
end
Expand All @@ -108,8 +108,8 @@ def tag_name(multiple = false, index = nil)
@template_object.field_name(@object_name, sanitized_method_name, multiple: multiple, index: index)
end

def tag_id(index = nil)
@template_object.field_id(@object_name, @method_name, index: index)
def tag_id(index = nil, namespace = nil)
@template_object.field_id(@object_name, @method_name, index: index, namespace: namespace)
end

def sanitized_method_name
Expand Down
30 changes: 30 additions & 0 deletions actionview/test/template/form_helper_test.rb
Expand Up @@ -1689,6 +1689,22 @@ def test_form_for_field_name_with_blank_as
assert_dom_equal expected, output_buffer
end

def test_form_for_field_id_with_namespace
form_for(Post.new, namespace: :special) do |form|
concat form.label(:title)
concat form.text_field(:title, aria: { describedby: form.field_id(:title, :error) })
concat tag.span("is blank", id: form.field_id(:title, :error))
end

expected = whole_form("/posts", "special_new_post", "new_post") do
'<label for="special_post_title">Title</label>' \
'<input id="special_post_title" name="post[title]" type="text" aria-describedby="special_post_title_error">' \
'<span id="special_post_title_error">is blank</span>'
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))
Expand Down Expand Up @@ -1797,6 +1813,20 @@ def test_form_for_field_name_with_method_names_and_multiple_and_index
assert_dom_equal expected, output_buffer
end

def test_form_for_field_id_with_namespace_and_index
form_for(Post.new, namespace: :special, index: 1) do |form|
concat form.text_field(:title, aria: { describedby: form.field_id(:title, :error) })
concat tag.span("is blank", id: form.field_id(:title, :error))
end

expected = whole_form("/posts", "special_new_post", "new_post") do
'<input id="special_post_1_title" name="post[1][title]" type="text" aria-describedby="special_post_1_title_error">' \
'<span id="special_post_1_title_error">is blank</span>'
end

assert_dom_equal expected, output_buffer
end

def test_form_for_with_collection_radio_buttons
post = Post.new
def post.active; false; end
Expand Down