Skip to content

Commit 1939c20

Browse files
authored
allow to skip persistent id generation (#3677)
Fixes #3673
1 parent c0e6615 commit 1939c20

File tree

2 files changed

+76
-22
lines changed

2 files changed

+76
-22
lines changed

lib/phoenix_component.ex

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,6 +2711,14 @@ defmodule Phoenix.Component do
27112711
"""
27122712
)
27132713

2714+
attr.(:skip_persistent_id, :boolean,
2715+
default: false,
2716+
doc: """
2717+
Skip the automatic rendering of hidden _persistent_id fields used for reordering
2718+
inputs.
2719+
"""
2720+
)
2721+
27142722
attr.(:options, :list,
27152723
default: [],
27162724
doc: """
@@ -2733,11 +2741,42 @@ defmodule Phoenix.Component do
27332741
|> Keyword.merge(assigns.options)
27342742

27352743
forms = parent_form.impl.to_form(parent_form.source, parent_form, field_name, options)
2744+
2745+
forms =
2746+
case assigns do
2747+
%{skip_persistent_id: true} ->
2748+
forms
2749+
2750+
_ ->
2751+
apply_persistent_id(
2752+
parent_form,
2753+
forms,
2754+
field_name,
2755+
options
2756+
)
2757+
end
2758+
2759+
assigns = assign(assigns, :forms, forms)
2760+
2761+
~H"""
2762+
<%= for finner <- @forms do %>
2763+
<%= if !@skip_hidden do %>
2764+
<%= for {name, value_or_values} <- finner.hidden,
2765+
name = name_for_value_or_values(finner, name, value_or_values),
2766+
value <- List.wrap(value_or_values) do %>
2767+
<input type="hidden" name={name} value={value} />
2768+
<% end %>
2769+
<% end %>
2770+
{render_slot(@inner_block, finner)}
2771+
<% end %>
2772+
"""
2773+
end
2774+
2775+
defp apply_persistent_id(parent_form, forms, field_name, options) do
27362776
seen_ids = for f <- forms, vid = f.params[@persistent_id], into: %{}, do: {vid, true}
2737-
acc = {seen_ids, 0}
27382777

27392778
{forms, _} =
2740-
Enum.map_reduce(forms, acc, fn
2779+
Enum.map_reduce(forms, {seen_ids, 0}, fn
27412780
%Phoenix.HTML.Form{params: params} = form, {seen_ids, index} ->
27422781
id =
27432782
case params do
@@ -2766,20 +2805,7 @@ defmodule Phoenix.Component do
27662805
{new_form, {Map.put(seen_ids, id, true), index + 1}}
27672806
end)
27682807

2769-
assigns = assign(assigns, :forms, forms)
2770-
2771-
~H"""
2772-
<%= for finner <- @forms do %>
2773-
<%= if !@skip_hidden do %>
2774-
<%= for {name, value_or_values} <- finner.hidden,
2775-
name = name_for_value_or_values(finner, name, value_or_values),
2776-
value <- List.wrap(value_or_values) do %>
2777-
<input type="hidden" name={name} value={value} />
2778-
<% end %>
2779-
<% end %>
2780-
{render_slot(@inner_block, finner)}
2781-
<% end %>
2782-
"""
2808+
forms
27832809
end
27842810

27852811
defp next_id(idx, %{} = seen_ids) do

test/phoenix_component/components_test.exs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ defmodule Phoenix.LiveView.ComponentsTest do
505505

506506
template = ~H"""
507507
<.form :let={f} as={:myform}>
508-
<.inputs_for :let={finner} field={f[:inner]} }>
508+
<.inputs_for :let={finner} field={f[:inner]}>
509509
<% 0 = finner.index %>
510510
<input id={finner[:foo].id} name={finner[:foo].name} type="text" />
511511
</.inputs_for>
@@ -526,7 +526,7 @@ defmodule Phoenix.LiveView.ComponentsTest do
526526

527527
template = ~H"""
528528
<.form :let={f} as={:myform}>
529-
<.inputs_for :let={finner} field={f[:inner]} } id="test" as={:name}>
529+
<.inputs_for :let={finner} field={f[:inner]} id="test" as={:name}>
530530
<input id={finner[:foo].id} name={finner[:foo].name} type="text" />
531531
</.inputs_for>
532532
</.form>
@@ -542,7 +542,7 @@ defmodule Phoenix.LiveView.ComponentsTest do
542542

543543
template = ~H"""
544544
<.form :let={f} as={:myform}>
545-
<.inputs_for :let={finner} field={f[:inner]} } as={:name}>
545+
<.inputs_for :let={finner} field={f[:inner]} as={:name}>
546546
<input id={finner[:foo].id} name={finner[:foo].name} type="text" />
547547
</.inputs_for>
548548
</.form>
@@ -562,7 +562,7 @@ defmodule Phoenix.LiveView.ComponentsTest do
562562

563563
template = ~H"""
564564
<.form :let={f} as={:myform}>
565-
<.inputs_for :let={finner} field={f[:inner]} } default={%{foo: "123"}}>
565+
<.inputs_for :let={finner} field={f[:inner]} default={%{foo: "123"}}>
566566
<input id={finner[:foo].id} name={finner[:foo].name} type="text" value={finner[:foo].value} />
567567
</.inputs_for>
568568
</.form>
@@ -585,7 +585,6 @@ defmodule Phoenix.LiveView.ComponentsTest do
585585
<.inputs_for
586586
:let={finner}
587587
field={f[:inner]}
588-
}
589588
default={[%{foo: "456"}]}
590589
prepend={[%{foo: "123"}]}
591590
append={[%{foo: "789"}]}
@@ -613,7 +612,7 @@ defmodule Phoenix.LiveView.ComponentsTest do
613612

614613
template = ~H"""
615614
<.form :let={f} as={:myform}>
616-
<.inputs_for :let={finner} field={f[:inner]} } options={[foo: "bar"]}>
615+
<.inputs_for :let={finner} field={f[:inner]} options={[foo: "bar"]}>
617616
<p>{finner.options[:foo]}</p>
618617
</.inputs_for>
619618
</.form>
@@ -623,6 +622,35 @@ defmodule Phoenix.LiveView.ComponentsTest do
623622
assert [p] = Floki.find(html, "p")
624623
assert Floki.text(p) =~ "bar"
625624
end
625+
626+
test "can disable persistent ids" do
627+
assigns = %{}
628+
629+
template = ~H"""
630+
<.form :let={f} as={:myform}>
631+
<.inputs_for
632+
:let={finner}
633+
field={f[:inner]}
634+
default={[%{foo: "456"}, %{foo: "789"}]}
635+
prepend={[%{foo: "123"}]}
636+
append={[%{foo: "101112"}]}
637+
skip_persistent_id
638+
>
639+
<input id={finner[:foo].id} name={finner[:foo].name} type="text" value={finner[:foo].value} />
640+
</.inputs_for>
641+
</.form>
642+
"""
643+
644+
assert t2h(template) ==
645+
~X"""
646+
<form>
647+
<input id="myform_inner_0_foo" name="myform[inner][0][foo]" type="text" value="123"></input>
648+
<input id="myform_inner_1_foo" name="myform[inner][1][foo]" type="text" value="456"></input>
649+
<input id="myform_inner_2_foo" name="myform[inner][2][foo]" type="text" value="789"></input>
650+
<input id="myform_inner_3_foo" name="myform[inner][3][foo]" type="text" value="101112"></input>
651+
</form>
652+
"""
653+
end
626654
end
627655

628656
describe "live_file_input/1" do

0 commit comments

Comments
 (0)