<.form
for={@form}
phx-change="validate_angle_range"
phx-submit="save_angle_range"
>
<.angle_slider
field={@form[:angle]}
marker_values={[0, 90, 180, 270]}
on_value_change="angle_range_changed"
class="angle-slider"
>
<:label>Angle (0–90)</:label>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.angle_slider>
<.action type="submit" class="button button--accent">Submit</:action>
</.form>
defmodule MyAppWeb.AngleSliderFormLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
ecto_form =
%MyApp.Forms.AngleSlider{}
|> MyApp.Forms.AngleSlider.changeset_validate(%{})
|> Phoenix.Component.to_form(as: :angle_slider_ecto, id: "angle-slider-live-form-ecto")
{:ok, assign(socket, :ecto_form, ecto_form)}
end
def handle_event("validate", %{"angle_slider_ecto" => params}, socket) do
changeset =
%MyApp.Forms.AngleSlider{}
|> MyApp.Forms.AngleSlider.changeset_validate(params)
|> Map.put(:action, :validate)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :validate,
as: :angle_slider_ecto,
id: "angle-slider-live-form-ecto"
)
)}
end
def handle_event("save", %{"angle_slider_ecto" => params}, socket) do
case MyApp.Forms.AngleSlider.changeset_validate(%MyApp.Forms.AngleSlider{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(
MyApp.Forms.AngleSlider.changeset_validate(%MyApp.Forms.AngleSlider{}, params),
as: :angle_slider_ecto,
id: "angle-slider-live-form-ecto"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :insert,
as: :angle_slider_ecto,
id: "angle-slider-live-form-ecto"
)
)}
end
end
end
defmodule MyApp.Forms.AngleSlider do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :angle, :float, default: 0.0
end
def changeset(form, attrs \\ %{}) do
form
|> cast(attrs, [:angle])
|> validate_required([:angle])
end
def changeset_validate(form, attrs \\ %{}) do
form
|> cast(attrs, [:angle])
|> validate_required([:angle])
|> validate_number(:angle,
greater_than_or_equal_to: 0.0,
less_than_or_equal_to: 90.0,
message: "must be between 0 and 90"
)
end
end