DSL for declaring form-visibility predicates and async-validation
rules on top of Caravela.Live.Domain.
A form-domain module compiles into a regular Caravela.Live.Domain
(so all state/updater/event sugar is available) plus a small amount
of form-specific introspection consumed by the Svelte form generator
(Caravela.Gen.SvelteForm) and by the form LiveView at runtime.
defmodule MyApp.BookFormDomain do
use Caravela.Live.Form,
entity: MyApp.Library.V1.Book,
context_fields: [:current_user]
state do
field :book, :map, default: nil
field :attrs, :map, default: %{}
field :errors, :map, default: %{}
field :field_visibility, :map, default: %{}
field :async_errors, :map, default: %{}
field :saving, :boolean, default: false
field :flash_message, :string, default: nil
end
visible :published_at, fn assigns ->
Map.get(assigns.attrs, :published) == true
end
visible :price, fn assigns ->
assigns.current_user.role in [:admin, :editor]
end
validate_async :isbn, debounce: 500, fn value, _assigns ->
case MyApp.ISBNService.validate(value) do
:ok -> :ok
{:error, reason} -> {:error, reason}
end
end
endAfter compilation the module exposes:
__caravela_form__/0— form metadata (entity, context fields, visible/async field lists, debounces).__caravela_form_visibility__/1— compute thefield_visibilitymap from an assigns map by running everyvisiblepredicate.__caravela_form_visible__/2— per-field visibility predicate (fallback returnstruefor undeclared fields).__caravela_form_validate_async__/3— dispatches a field's async validator; returns:okor{:error, reason}.
Summary
Functions
Declare an async validator for a field.
Declare a visibility predicate for a field. The function receives the LiveView assigns and must return a boolean.
Functions
Declare an async validator for a field.
validate_async :isbn, debounce: 500, fn value, assigns ->
MyApp.ISBNService.validate(value)
endThe validator is a function of arity 2 (value, assigns) that
returns :ok or {:error, reason}. The optional :debounce option
(milliseconds) is exposed as metadata so the generated Svelte form
can debounce client-side input before pushing the
"validate_async" event back to the LiveView.
Declare a visibility predicate for a field. The function receives the LiveView assigns and must return a boolean.
visible :published_at, fn assigns ->
Map.get(assigns.attrs, :published) == true
endThe predicate is evaluated server-side; the computed truth value is
sent to the Svelte component as field_visibility.<name> so that
{#if field_visibility.published_at} renders reactively.