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
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}
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 structparams- 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_typesconfig (seeDynamicForm.FieldTypes):visibility_params- params used to evaluatevisibleIf/requiredIfexpressions instead ofparams. 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?
trueNote
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)
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"}
]