DynamicForm.Changeset (DynamicForm v0.17.6)

Copy Markdown View Source

Helper functions for creating dynamic changesets from DynamicForm.Instance configurations.

This module converts a form instance into an Ecto changeset, allowing for validation and form handling using Phoenix's standard patterns.

Summary

Functions

Builds a map of question names to their Ecto types.

Creates a changeset from a DynamicForm.Instance configuration.

Extracts only Question structs from the elements list, filtering out Elements.

Functions

build_types_map(questions, field_types \\ %{})

Builds a map of question names to their Ecto types.

Example

iex> questions = [
...>   %DynamicForm.Instance.Question{name: "email", type: "text"},
...>   %DynamicForm.Instance.Question{name: "age", type: "text", inputType: "number"}
...> ]
iex> DynamicForm.Changeset.build_types_map(questions)
%{email: :string, age: :decimal}

create_changeset(instance, params \\ %{}, opts \\ [])

Creates a changeset from a DynamicForm.Instance configuration.

Only form questions are included in the changeset. Elements (panels, HTML, etc.) are filtered out as they don't collect user input.

Parameters

  • instance - The DynamicForm.Instance struct
  • params - The form parameters to validate (defaults to empty map)
  • opts - Options:
    • :custom_field_types - a per-form custom field types map, merged over the :dynamic_form, :custom_field_types config (see DynamicForm.FieldTypes)
    • :visibility_params - params used to evaluate visibleIf/requiredIf expressions instead of params. Used internally when validating paneldynamic entries, where expressions can reference both panel-local ({panel.field}) and form-level values

Returns

An Ecto.Changeset that can be used with Phoenix forms.

Example

iex> instance = %DynamicForm.Instance{...}
iex> changeset = DynamicForm.Changeset.create_changeset(instance, %{"email" => "test@example.com"})
iex> changeset.valid?
true

Note

If you have JSON or a map, decode it to an Instance struct first:

# Decode at the edge
instance = DynamicForm.Instance.decode!(json_or_map)
changeset = DynamicForm.Changeset.create_changeset(instance, params)

get_questions(elements)

Extracts only Question structs from the elements list, filtering out Elements.

Recursively extracts questions from panel elements that contain nested elements.

Example

iex> elements = [
...>   %DynamicForm.Instance.Element{name: "intro", type: "html"},
...>   %DynamicForm.Instance.Question{name: "email", type: "text"},
...>   %DynamicForm.Instance.Element{
...>     name: "address-panel",
...>     type: "panel",
...>     elements: [
...>       %DynamicForm.Instance.Question{name: "city", type: "text"}
...>     ]
...>   }
...> ]
iex> DynamicForm.Changeset.get_questions(elements)
[
  %DynamicForm.Instance.Question{name: "email", type: "text"},
  %DynamicForm.Instance.Question{name: "city", type: "text"}
]