sodapopcan
New `to_form/2` in LiveView 1.18.2
I was wondering if there are any discussions around the new to_form/2 in LiveView 1.18.2. I’ve RTFM’d but there is just some dissonance in the change as it’s not mentioned in the changelog and it looks like we just need :let in nested inputs now? I am in no way complaining here, it’s def a step forward, it just caught me off guard and I’d love to know where I can follow along. Is the mailing list is best?
Thanks!
EDIT: I searched for to_form on the mailing list and found nothing.
Marked As Solved
LostKobrakai
The reason for the changes are meant to aid in LVs change tracking. Before the mentioned changes any update to the form would essentially rerender the whole form, that’s afaik meant to be gone/working better now.
Also Liked
mcrumm
Re: nested inputs, the addition of <Phoenix.Component.inputs_for> is one of the most recent changes. It replaces inputs_for() from Phoenix.HTML and it includes hidden inputs automatically (thanks @LostKobrakai
).
Here is a naive but complete example of rendering nested inputs:
# my_app_web/live/nested_live.ex
defmodule MyAppWeb.NestedLive do
use MyAppWeb, :live_view
defmodule Guestlist do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :event_name, :string
embeds_many :guests, Guest do
field :name, :string
end
end
def changeset(form, params \\ %{}) do
form
|> cast(params, [:event_name])
|> validate_required([:event_name])
|> cast_embed(:guests, with: &guest_changeset/2)
end
def guest_changeset(guestlist, params) do
guestlist
|> cast(params, [:name])
|> validate_required([:name])
end
end
@impl Phoenix.LiveView
def mount(_params, _session, socket) do
guestlist = %Guestlist{
event_name: "My New Event",
guests: [
%Guestlist.Guest{name: ""},
%Guestlist.Guest{name: ""},
%Guestlist.Guest{name: ""}
]
}
changeset = guestlist |> Guestlist.changeset()
{:ok,
socket
|> assign(:guestlist, guestlist)
|> assign_form(changeset)}
end
@impl Phoenix.LiveView
def handle_event("change", %{"guestlist" => params}, socket) do
changeset =
socket.assigns.guestlist
|> Guestlist.changeset(params)
|> Map.put(:action, :validate)
{:noreply, assign_form(socket, changeset)}
end
def handle_event("submit", %{"guestlist" => params}, socket) do
case fake_save_guestlist(socket.assigns.guestlist, params) do
{:ok, _guestlist} ->
{:noreply,
socket
|> put_flash(:info, "Guestlist saved!")
|> push_navigate(to: "/")}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign_form(socket, changeset)}
end
end
defp assign_form(socket, %Ecto.Changeset{} = changeset) do
assign(socket, :form, to_form(changeset))
end
defp fake_save_guestlist(%Guestlist{} = guestlist, params) do
guestlist
|> Guestlist.changeset(params)
|> Ecto.Changeset.apply_action(:save)
end
@impl Phoenix.LiveView
def render(assigns) do
~H"""
<.form for={@form} id="nested-form" phx-change="change" phx-submit="submit">
<.input type="text" field={@form[:event_name]} label="Title" />
<fieldset class="my-4">
<legend class="py-2">Guests</legend>
<.inputs_for :let={f_nested} field={@form[:guests]}>
<.input type="text" field={f_nested[:name]} label={"Name #{f_nested.index + 1}"} />
</.inputs_for>
</fieldset>
<.button type="submit">Submit</.button>
</.form>
"""
end
end
Note on LiveView v0.18.13 the <.form> component warns that for is a required attribute but it is not. Anyone should feel free to PR that change ![]()
zachallaun
There have been a handful of pretty big new things popping up in LiveView without much fanfare, but if I were to guess, we’ll be hearing a lot more about these with the full Phoenix 1.7 release. Looking at the git history, to_form/2 landed just a few weeks ago. I’m just speculating, but given the sheer number of improvements present between Phoenix 1.7 and LiveView 0.18.*, I’d bet that the Phoenix team decided that it made the most sense to get things locked down and then release a mega-post/coordinated set of posts covering it all instead of drip-feeding for months.
sodapopcan
Ya, I was thinking a lot about the documentation and what you’re describing. The quality is extremely good but searching hexdocs can be quite frustrating. I often can’t remember if something is in the guides or in the module docs and then, when it comes to Phoenix, what package it is in. I always use google or ddg to search hexdocs because there is no way to search across packages—at least no evident way, it’s very possible I’m missing something obvious. But overall the search is not great. For example, if you search “liveview” on the homepage it gives you five results, none of which are LiveView itself (I’m aware there are instructions below on how to jump to packages via the URL but that is not my point). Basically, when something changes or is added or removed, it’s not always evident where to look.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









