MishkaGervaz.Form.Types.Field.Relation (MishkaGervaz v0.0.2)

Copy Markdown View Source

Relation field type for selecting related records in forms.

Follows the same pattern as MishkaGervaz.Table.Types.Filter.Relation.

Modes

  • :static - Load all options at once (default, for small datasets)
  • :load_more - Paginated with "Load more" button
  • :search - Searchable single select
  • :search_multi - Searchable multi select

Examples

field :site_id, :relation do
  mode :static
  display_field :name
end

field :category_id, :relation do
  mode :search_multi
  search_field :name
  min_chars 1
end

Why the rendered ids carry the form's id

Every DOM id this type hands the adapter is scoped by the id of the form component that is rendering it — :table_id (the adapter's name for "the scope this control belongs to") comes from state_assigns.form_id, and :id comes from the Phoenix form field, which already carries the form's id. A page may mount two MishkaGervaz.Form.Web.Live components whose resources share a field name — /admin/dashboard/runtime/medias mounts one for MishkaCmsCore.Runtime.Media and one for MishkaCmsCore.Runtime.MediaCategory, and both have a site_id relation. Scoped only by field name, both would render search-select--site_id, and morphdom — which matches by id before anything else — would be free to patch one form's dropdown with the other form's markup.

See MishkaGervaz.Form.Behaviours.FieldType, MishkaGervaz.Form.Types.Field, and the table-side counterpart MishkaGervaz.Table.Types.Filter.Relation.

Summary

Functions

Renders the relation field input by building assigns and calling the UI adapter.

Whether field is a relation drawn as a plain select: :static, the default, or a mode this type does not know.

Functions

render_input(field, rel_data, state_assigns, ui)

@spec render_input(map(), map(), map(), module()) :: Phoenix.LiveView.Rendered.t()

Renders the relation field input by building assigns and calling the UI adapter.

Delegates to the appropriate UI adapter function based on mode:

ui.select/1 is named after the form field, form[<field>], and shows the field's value in field_values, or the form's value when field_values holds none.

select_mode?(field)

@spec select_mode?(map()) :: boolean()

Whether field is a relation drawn as a plain select: :static, the default, or a mode this type does not know.

The select posts its pick with the form's own params, as form[<field>], and MishkaGervaz.Form.Web.Events.put_select_picks/2 writes it into state.field_values on every validate and save.