DynamicForm.Instance (DynamicForm v1.0.0)

Copy Markdown View Source

Configuration struct that defines the complete form structure using SurveyJS-compatible format.

An Instance represents a complete form definition with all its elements (questions and panels), and validators.

SurveyJS Compatibility

This library uses SurveyJS-compatible JSON format for form definitions. See: https://surveyjs.io/form-library/documentation

Example

iex> instance = %DynamicForm.Instance{
...>   id: "contact-form",
...>   title: "Contact Form",
...>   description: "Get in touch with us",
...>   elements: [
...>     %DynamicForm.Instance.Element{
...>       name: "intro",
...>       type: "html",
...>       html: "<h2>Contact Information</h2>"
...>     },
...>     %DynamicForm.Instance.Question{
...>       name: "email",
...>       type: "text",
...>       inputType: "email",
...>       title: "Email Address",
...>       isRequired: true
...>     }
...>   ]
...> }

JSON Encoding/Decoding

Instances can be encoded to JSON and parsed back:

# Encode to JSON
json = Jason.encode!(instance)

# Parse from a JSON string or map
instance = DynamicForm.Parser.FromData.parse!(json)
instance = DynamicForm.Parser.FromData.parse!(map)

Slot-Defined Instances

Instances can also be built from <:field> slot entries via DynamicForm.form/1 (see DynamicForm.Parser.FromComponent). Questions and elements defined with a slot body carry the raw slot entry in their :slot field so the renderer can call Phoenix.Component.render_slot/2 on it. The :slot field holds a closure, so it is never JSON-encoded; use strip_slots/1 to compare two instances by definition alone.

Summary

Functions

Whether a definition's display text is blank: nil, false, or "".

The text labelling a question, or nil when the definition asks for none.

The mark shown beside a required question's label, or nil for none.

Returns a copy of the instance with all :slot fields removed.

Types

t()

@type t() :: %DynamicForm.Instance{
  description: String.t() | nil,
  elements: [Question.t() | Element.t()],
  id: String.t(),
  inserted_at: DateTime.t() | nil,
  metadata: map(),
  title: String.t() | nil,
  updated_at: DateTime.t() | nil
}

Functions

blank?(value)

Whether a definition's display text is blank: nil, false, or "".

Titles, labels, and headings accept all three to mean "render nothing", so a template can compute one without special-casing the absent case:

<:group name="totals" title={@compact && gettext("Totals")} />

label_text(question)

The text labelling a question, or nil when the definition asks for none.

A question with no title at all falls back to its capitalized name, so <:field type="text" name="email" /> still labels itself "Email". A title the definition sets blank (nil, false, or "") means "no label", and returns nil — callers render no label element, and no required marker, since there would be nothing for the marker to sit beside.

required_label_text(question)

The mark shown beside a required question's label, or nil for none.

A question that sets no requiredLabel uses "*". One that sets it blank (nil, false, or "") suppresses the mark while staying required, and any other value replaces it — "(required)", say.

strip_slots(instance)

Returns a copy of the instance with all :slot fields removed.

Slot-defined elements (see DynamicForm.Parser.FromComponent) carry their raw slot entry — including its inner_block closure — in the :slot field. Closures capture template assigns, so two otherwise-identical instances can compare unequal whenever those assigns change. Stripping the slots yields the form definition alone, which compares reliably with ==.