Phoenix Form
<.form for={@form} phx-submit="save_phoenix"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.select
class="select"
field={@form[:country]}
items={Corex.List.new([
%{label: "France", value: "fra"},
%{label: "Belgium", value: "bel"},
%{label: "Germany", value: "deu"},
%{label: "Netherlands", value: "nld"},
%{label: "Switzerland", value: "che"},
%{label: "Austria", value: "aut"}
])}
translation={%Corex.Select.Translation{placeholder: "Select a country"}}
deselectable
>
<:label>Country</:label>
<:trigger>
<.heroicon name="hero-chevron-down" class="icon" />
</:trigger>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.select>
<.action type="submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.SelectFormLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
phoenix_form =
Phoenix.Component.to_form(%{"country" => ""}, as: :select_phoenix, id: "select-live-form-phoenix")
{:ok, assign(socket, :phoenix_form, phoenix_form)}
end
def handle_event("save_phoenix", %{"select_phoenix" => params}, socket) do
country = params["country"] || ""
{:noreply,
assign(
socket,
:phoenix_form,
Phoenix.Component.to_form(%{"country" => country}, as: :select_phoenix, id: "select-live-form-phoenix")
)}
end
end
Phoenix Form + Ecto
<.form for={@ecto_form} phx-change="validate" phx-submit="save"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.select
id="select-live-form-ecto-country"
class="select"
field={@ecto_form[:country]}
items={form_country_items()}
translation={%Corex.Select.Translation{placeholder: "Select a country"}}
deselectable
>
<:label>Country</:label>
<:trigger>
<.heroicon name="hero-chevron-down" class="icon" />
</:trigger>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.select>
<.action type="submit" id="select-live-form-ecto-submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.SelectFormLive do
use MyAppWeb, :live_view
alias MyApp.Forms.CountryForm
def mount(_params, _session, socket) do
{:ok,
assign(
socket,
:ecto_form,
CountryForm.changeset(%CountryForm{}, %{})
|> Phoenix.Component.to_form(as: :select_ecto, id: "select-live-form-ecto")
)}
end
def handle_event("validate", %{"select_ecto" => params}, socket) do
changeset = CountryForm.changeset(%CountryForm{}, params)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset, action: :validate, as: :select_ecto, id: "select-live-form-ecto")
)}
end
def handle_event("save", %{"select_ecto" => params}, socket) do
case CountryForm.changeset(%CountryForm{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(
CountryForm.changeset(%CountryForm{}, params),
as: :select_ecto,
id: "select-live-form-ecto"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset, action: :insert, as: :select_ecto, id: "select-live-form-ecto")
)}
end
end
end
defmodule MyApp.Forms.CountryForm do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :country, :string
end
def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [:country])
|> validate_required([:country], message: "can't be blank")
end
end
Phoenix Form + Ecto + Controlled
<.form for={@ecto_controlled_form} phx-change="validate_controlled" phx-submit="save_controlled"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.select
id="select-live-form-ecto-controlled-country"
class="select"
field={@ecto_controlled_form[:country]}
items={form_country_items()}
translation={%Corex.Select.Translation{placeholder: "Select a country"}}
deselectable
controlled
>
<:label>Country</:label>
<:trigger>
<.heroicon name="hero-chevron-down" class="icon" />
</:trigger>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.select>
<.action type="submit" id="select-live-form-ecto-controlled-submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.SelectFormLive do
use MyAppWeb, :live_view
alias MyApp.Forms.CountryForm
def handle_event("validate_controlled", %{"select_ecto_controlled" => params}, socket) do
changeset = CountryForm.changeset(%CountryForm{}, params)
{:noreply,
assign(
socket,
:ecto_controlled_form,
Phoenix.Component.to_form(changeset,
action: :validate,
as: :select_ecto_controlled,
id: "select-live-form-ecto-controlled"
)
)}
end
def handle_event("save_controlled", %{"select_ecto_controlled" => params}, socket) do
case CountryForm.changeset(%CountryForm{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_controlled_form,
Phoenix.Component.to_form(
CountryForm.changeset(%CountryForm{}, params),
as: :select_ecto_controlled,
id: "select-live-form-ecto-controlled"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_controlled_form,
Phoenix.Component.to_form(changeset,
action: :insert,
as: :select_ecto_controlled,
id: "select-live-form-ecto-controlled"
)
)}
end
end
end
defmodule MyApp.Forms.CountryForm do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :country, :string
end
def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [:country])
|> validate_required([:country], message: "can't be blank")
end
end
Phoenix Form + Ecto + Invalid
<.form for={@ecto_invalid_form} phx-change="validate_invalid" phx-submit="save_invalid"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.select
id="select-live-form-ecto-invalid-country"
class="select"
field={@ecto_invalid_form[:country]}
items={form_country_items()}
translation={%Corex.Select.Translation{placeholder: "Select a country"}}
deselectable
invalid={Corex.FormField.invalid?(@ecto_invalid_form[:country])}
>
<:label>Country</:label>
<:trigger>
<.heroicon name="hero-chevron-down" class="icon" />
</:trigger>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.select>
<.action type="submit" id="select-live-form-ecto-invalid-submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.SelectFormLive do
use MyAppWeb, :live_view
alias MyApp.Forms.CountryForm
def handle_event("validate_invalid", %{"select_ecto_invalid" => params}, socket) do
changeset = CountryForm.changeset(%CountryForm{}, params)
{:noreply,
assign(
socket,
:ecto_invalid_form,
Phoenix.Component.to_form(changeset,
action: :validate,
as: :select_ecto_invalid,
id: "select-live-form-ecto-invalid"
)
)}
end
def handle_event("save_invalid", %{"select_ecto_invalid" => params}, socket) do
case CountryForm.changeset(%CountryForm{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_invalid_form,
Phoenix.Component.to_form(
CountryForm.changeset(%CountryForm{}, params),
as: :select_ecto_invalid,
id: "select-live-form-ecto-invalid"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_invalid_form,
Phoenix.Component.to_form(changeset,
action: :insert,
as: :select_ecto_invalid,
id: "select-live-form-ecto-invalid"
)
)}
end
end
end
defmodule MyApp.Forms.CountryForm do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :country, :string
end
def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [:country])
|> validate_required([:country], message: "can't be blank")
end
end