diff --git a/lib/phoenix_component.ex b/lib/phoenix_component.ex index 69617a4ef..484fe5418 100644 --- a/lib/phoenix_component.ex +++ b/lib/phoenix_component.ex @@ -2103,74 +2103,26 @@ defmodule Phoenix.Component do ~H""" <%= for finner <- @forms do %> - <.hidden_inputs :if={!@skip_hidden} form={finner} /> + <%= unless @skip_hidden do %> + <%= for {name, value_or_values} <- finner.hidden, + name = name_for_value_or_values(finner, name, value_or_values), + value <- List.wrap(value_or_values) do %> + + <% end %> + <% end %> <%= render_slot(@inner_block, finner) %> <% end %> """ end - @doc """ - Renders hidden inputs for a form. - - [INSERT LVATTRDOCS] - - This function is built on top of `Phoenix.HTML.Form.hidden_inputs_for/1`. - - ## Examples - - ```heex - <.form - :let={f} - for={@changeset} - phx-change="change_name" - > - <.inputs_for :let={f_nested} field={{:f, :nested}} skip_hidden> - <%= text_input f_nested, :name %> - <.hidden_inputs form={f_nested} /> - - - ``` - """ - - attr.(:form, Phoenix.HTML.Form, - required: true, - doc: "A %Phoenix.HTML.Form{} struct." - ) - - def hidden_inputs(%{form: form} = assigns) do - inputs = - Enum.flat_map(form.hidden, fn - {field, values} when is_list(values) -> - id = input_id(form, field) - name = input_name(form, field) - - values - |> Enum.with_index() - |> Enum.map(fn {value, index} -> - %{ - id: id <> "_" <> Integer.to_string(index), - name: name <> "[]", - value: value - } - end) - - {field, value} -> - [ - %{ - id: input_id(form, field), - name: input_name(form, field), - value: value - } - ] - end) - - assigns = assign(assigns, :inputs, inputs) + @spec name_for_value_or_values(Phoenix.HTML.Form.t() | atom, atom | String.t(), term) :: + String.t() + defp name_for_value_or_values(form, field, values) when is_list(values) do + input_name(form, field) <> "[]" + end - ~H""" - <%= for opts <- @inputs do %> - - <% end %> - """ + defp name_for_value_or_values(form, field, _value) do + input_name(form, field) end @spec input_name(Phoenix.HTML.Form.t() | atom, atom | String.t()) :: String.t() @@ -2184,17 +2136,6 @@ defmodule Phoenix.Component do defp input_name(name, field) when (is_atom(name) and is_atom(field)) or is_binary(field), do: "#{name}[#{field}]" - @spec input_id(Phoenix.HTML.Form.t() | atom, atom | String.t()) :: String.t() - defp input_id(%{id: nil}, field), do: "#{field}" - - defp input_id(%{id: id}, field) when is_atom(field) or is_binary(field) do - "#{id}_#{field}" - end - - defp input_id(name, field) when (is_atom(name) and is_atom(field)) or is_binary(field) do - "#{name}_#{field}" - end - @doc """ Generates a link for live and href navigation. diff --git a/test/phoenix_component/components_test.exs b/test/phoenix_component/components_test.exs index e25bcf680..1f2aa5921 100644 --- a/test/phoenix_component/components_test.exs +++ b/test/phoenix_component/components_test.exs @@ -603,90 +603,6 @@ defmodule Phoenix.LiveView.ComponentsTest do end end - describe "hidden_inputs/1" do - test "doesn't render anything if there are no hidden fields" do - assigns = %{} - - template = ~H""" - <.form :let={f} for={:myform}> - <.inputs_for :let={finner} field={{f, :inner}} default={%{foo: "123"}} skip_hidden> - <.hidden_inputs form={finner} /> - - - """ - - html = parse(template) - - assert [ - {"form", [], []} - ] = html - end - - test "renders hidden input for single value hidden field" do - assigns = %{} - - template = ~H""" - <.form :let={f} for={:myform}> - <.inputs_for :let={finner} field={{f, :inner}} default={%{id: 12, foo: "123"}} skip_hidden> - <.hidden_inputs form={Map.put(finner, :hidden, [id: finner.data.id])} /> - - - """ - - html = parse(template) - - assert [ - {"form", [], - [ - {"input", - [ - {"type", "hidden"}, - {"id", "myform_inner_id"}, - {"name", "myform[inner][id]"}, - {"value", "12"} - ], []} - ]} - ] = html - end - - test "renders hidden input for multiple value hidden field" do - assigns = %{} - - template = ~H""" - <.form :let={f} for={:myform}> - <.inputs_for :let={finner} field={{f, :inner}} default={%{type: ["abc", "def"], foo: "123"}} skip_hidden> - <.hidden_inputs form={Map.put(finner, :hidden, [type: finner.data.type])} /> - - - """ - - html = parse(template) - - assert [ - {"form", [], - [ - { - "input", - [ - {"type", "hidden"}, - {"id", "myform_inner_type_0"}, - {"name", "myform[inner][type][]"}, - {"value", "abc"} - ], - [] - }, - {"input", - [ - {"type", "hidden"}, - {"id", "myform_inner_type_1"}, - {"name", "myform[inner][type][]"}, - {"value", "def"} - ], []} - ]} - ] = html - end - end - describe "live_file_input/1" do test "renders attributes" do assigns = %{