simple_form default for @as overrides form values
rmoorman opened this issue · 2 comments
While using the simple_form
component (that is generated by default using mix phx.new
), the following problem grabbed my attention. I was building a form schema inside a live view and wanted to render that form using the simple_form
component.
The example states that it should be used like this
<.simple_form for={@form} phx-change="validate" phx-submit="save">
<.input field={@form[:email]} label="Email"/>
<.input field={@form[:username]} label="Username" />
<:actions>
<.button>Save</.button>
</:actions>
</.simple_form>
But I thought, that it would be more consistent to use the <.simple_form :let={f} for={@form}>
in my case (because I was likely to also use inputs_for
in that project). But using :let
does cause the struct f
to contain nil
as it's name, which in turn messes up the field names and value groupings of the form (as the prefix based on the schema name is missing).
Currently, the following code:
defmodule HelloWeb.SimpleFormLetBindingLive do
use HelloWeb, :live_view
defmodule FormSchema do
use Ecto.Schema
import Ecto.Changeset
@primary_key false
embedded_schema do
field(:foo, :string)
field(:bar, :string)
end
def changeset(data, attrs) do
data
|> cast(attrs, [:foo, :bar])
|> validate_required([:foo, :bar])
end
end
@impl Phoenix.LiveView
def handle_params(_, _, socket) do
form = to_form(FormSchema.changeset(%FormSchema{}, %{}))
socket = assign(socket, form: form)
{:noreply, socket}
end
@impl Phoenix.LiveView
def render(assigns) do
~H"""
<.simple_form :let={f} for={@form}>
<table>
<tr>
<th><code>@form.name</code></th>
<td><code><%= inspect(@form.name) %></code></td>
</tr>
<tr>
<th><code>f.name</code></th>
<td><code><%= inspect(f.name) %></code></td>
</tr>
</table>
<.input field={@form[:foo]} label="Foo" />
<.input field={f[:bar]} label="Bar" />
</.simple_form>
"""
end
end
produces the following results
Which seems odd to me.
I prepared an example repository that can be used to reproduce the issue.
The issue is in the generated simple_form:
You can see it sets the default of @as
to nil. You can change it in your app, I will migrate this to the Phoenix repo.
Thank you @josevalim for having a look!
I suppose the suggestion of using as
is about working around the problem by adding as={@form.name}
or something like that within render/1
? (which does indeed work)
And if there is anything else I can do to help moving this forward, please let me know.