Phoenix
<.form for={@form} phx-submit="save_phoenix"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.color_picker
name={@form[:color].name}
value={@form[:color].value || "#3b82f6"}
class="color-picker">
<:label>Color</:label>
</.color_picker>
<.action type="submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.ColorPickerFormLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
phoenix_form =
Phoenix.Component.to_form(%{"color" => "#ff0000"}, as: :color_picker_phoenix, id: "color-picker-live-form-phoenix")
{:ok, assign(socket, :phoenix_form, phoenix_form)}
end
def handle_event("save_phoenix", %{"color_picker_phoenix" => params}, socket) do
color = params["color"] || ""
{:noreply,
assign(
socket,
:phoenix_form,
Phoenix.Component.to_form(%{"color" => color}, as: :color_picker_phoenix, id: "color-picker-live-form-phoenix")
)}
end
end
نموذج Phoenix (changeset)
<.form
for={@form}
phx-change="validate_validate"
phx-submit="save_validate"
class="flex flex-col gap-space-lg w-full max-w-xl"
>
<.color_picker
name={@form[:color].name}
value={@color}
on_value_change="color_changed_validate"
class="color-picker">
<:label>Color</:label>
</.color_picker>
<.color_form_errors form={@form} />
<.action type="submit" class="button ui-accent">
Submit
</.action>
</.form>
defmodule MyAppWeb.ColorPickerFormLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
ecto_form =
%MyApp.Form.ColorPickerForm{}
|> MyApp.Form.ColorPickerForm.changeset_validate(%{})
|> Phoenix.Component.to_form(as: :color_picker_ecto, id: "color-picker-live-form-ecto")
{:ok, assign(socket, :ecto_form, ecto_form)}
end
def handle_event("validate", %{"color_picker_ecto" => params}, socket) do
changeset =
%MyApp.Form.ColorPickerForm{}
|> MyApp.Form.ColorPickerForm.changeset_validate(params)
|> Map.put(:action, :validate)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :validate,
as: :color_picker_ecto,
id: "color-picker-live-form-ecto"
)
)}
end
def handle_event("save", %{"color_picker_ecto" => params}, socket) do
case MyApp.Form.ColorPickerForm.changeset_validate(%MyApp.Form.ColorPickerForm{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(
MyApp.Form.ColorPickerForm.changeset_validate(%MyApp.Form.ColorPickerForm{}, params),
as: :color_picker_ecto,
id: "color-picker-live-form-ecto"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :insert,
as: :color_picker_ecto,
id: "color-picker-live-form-ecto"
)
)}
end
end
end
defmodule MyApp.Form.ColorPickerForm do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :color, :string, default: "#3b82f6"
end
def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [:color])
|> validate_required([:color])
end
def changeset_validate(form, attrs \\ %{}) do
form
|> cast(attrs, [:color])
|> validate_required([:color])
|> validate_alpha_max_50()
end
defp validate_alpha_max_50(changeset) do
with value when is_binary(value) <- get_field(changeset, :color),
[_, alpha] <-
Regex.run(~r/rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*([\d.]+)\s*\)/, value),
{float_val, _} <- Float.parse(alpha),
true <- float_val > 0.5 do
add_error(changeset, :color, "maximum alpha allowed is 50%")
else
_ -> changeset
end
end
end