MishkaGervaz.Form.Web.Live (MishkaGervaz v0.0.2)

Copy Markdown View Source

LiveComponent for MishkaGervaz admin forms.

This is a thin orchestrator that delegates to specialized modules:

  • State - State management
  • DataLoader - Record loading and relation options
  • Events - Event handling
  • Renderer - Template rendering

Usage

Create mode (new record):

<.live_component
  module={MishkaGervaz.Form.Web.Live}
  id="post-form"
  resource={MyApp.Post}
  current_user={@current_user}
/>

Edit mode (existing record):

<.live_component
  module={MishkaGervaz.Form.Web.Live}
  id="post-form"
  resource={MyApp.Post}
  current_user={@current_user}
  record_id={@post_id}
/>

Required Assigns

  • id - Unique component ID
  • resource - Ash resource module with MishkaGervaz.Resource extension
  • current_user - Current user for authorization

Optional Assigns

  • record_id - ID of record to edit (nil for create mode)
  • defaults - Map of default field values for create mode (e.g., %{workspace_id: @workspace_id}). A picker's default is saved only while the picker still holds it: once it is cleared, or emptied because a field it depends on changed, the save leaves it out. An update that leaves the key out, such as the send_update/2 a table's Edit sends with only a record_id, keeps the defaults the form has. Pass defaults: nil to drop them.
  • reset - true starts the form over on its record_id, even when that is the record already open, or nil while the form is already on create. See "Opening a form again".

Opening a form again

A form that stays mounted while it is hidden — in a modal that is shown and hidden, say — keeps what was typed, its errors and its pending uploads through a close that sends it nothing, such as a modal's close icon. Whatever opens it again starts it over:

send_update(MishkaGervaz.Form.Web.Live, id: "post-form", record_id: nil, reset: true)

A create returns to the empty create form, with the form's defaults; an edit reads its record again. The uploads are cancelled. A create is drawn once without its <form> before the empty one is built, so every control is drawn anew, a phx-update="ignore" one included, and reads the new value. A table's Edit sends reset: true with the row's record_id. A button that opens the form without asking the server uses reset/2.

After a save

A create save always returns the form to an empty create form. An update save depends on how the form was mounted:

  • mounted with a record_id assign (even nil) — the form stays on the saved record, reloaded for editing. Pass a different record_id, or nil, to move it.
  • mounted without one, and opened for editing with send_update/2 — the form returns to an empty create form.

Parent LiveView Integration

The component sends messages to the parent for certain actions:

def handle_info({:form_saved, :create, result}, socket), do: ...
def handle_info({:form_saved, :update, result}, socket), do: ...
def handle_info({:form_cancelled, resource}, socket), do: ...
def handle_info({:form_event, event, params}, socket), do: ...
def handle_info({:add_nested_field, field_name}, socket), do: ...
def handle_info({:remove_nested_field, field_name, index}, socket), do: ...

See MishkaGervaz.Form.Web.State (state shape + override surface), MishkaGervaz.Form.Web.DataLoader (record + relation loading), MishkaGervaz.Form.Web.Events (event handling), MishkaGervaz.Form.Web.Renderer (template dispatch), MishkaGervaz.Form.Web.UploadHelpers, and MishkaGervaz.Form.Behaviours.Template.

Summary

Functions

The JS command that starts the form with this component id over as an empty create form, as reset: true with a nil record_id does. For a button that shows a hidden form on the client

Functions

reset(js \\ %JS{}, id)

The JS command that starts the form with this component id over as an empty create form, as reset: true with a nil record_id does. For a button that shows a hidden form on the client:

<button phx-click={MishkaGervaz.Form.Web.Live.reset("post-form") |> show_modal("post-modal")}>

It pushes the form's reset event to the element with the id "<id>-form-wrapper".