Skip to content

API reference

Every public method is listed here, grouped by lifecycle. Most methods are chainable and return the same FormController. Click into the per-method pages of the project repository for the full signature, parameter table and runnable example.

  • form(target, options?) — bind a controller to an HTMLFormElement. The main entry point.
  • element — the bound form (f is an alias).
  • reset() — restore native form values and clear errors.
  • destroy() — tear down listeners, observer, and caches.
  • browser — module-level singleton that wraps form() with newForm / destroyForm / available. Mirrors the IIFE surface without auto-installing a global.
  • browser.newForm — build + register a controller under browser.available[id].
  • browser.destroyForm — destroy + unregister a controller by id.
  • browser.available — registry of active controllers keyed by id.
  • getData() — return plain object + FormData for the form.
  • getState() — return a snapshot of values, errors, and metadata.
  • append(options) — inject a DOM node into the form.

These do not require a controller. They accept plain values or a raw HTMLFormElement and return results — safe to tree-shake into any bundle.


Each method below links to the dedicated page in the project repository for the full signature, parameters, return shape, behaviour tables, and runnable examples.

Creates a new controller bound to a form. This is the main entry point of @samline/forms.

function form(
target: FormTarget,
options?: FormControllerOptions
): FormController
  • target — string id, HTMLFormElement, ref-like { current } object, or null/undefined.
  • options — controller configuration. See Configuration.

On creation the controller wires input, change, and submit listeners at the form level, starts a MutationObserver on the form subtree, optionally enables autoSubmit, and runs an initial validation pass when autoValidate is enabled.

Read-only getter for the bound HTMLFormElement, or null if the binding target was unresolved at construction time. f is an alias kept short for fluent setup.

readonly element: HTMLFormElement | null
readonly f: HTMLFormElement | null

Restores the form to its initial state: native field values reset, manual and validation errors cleared, visual attributes stripped, subscribers notified.

Tears the controller down. Removes all DOM listeners, disconnects the MutationObserver, clears caches, drops subscribers and submit handlers, and resets internal state. Idempotent — calling it more than once is safe.

Registers a handler that runs when the form is submitted and validation passes. Multiple handlers can be registered; each runs in registration order.

onSubmit(
callback: FormSubmitHandler,
preventDefault?: boolean // default: true
): FormController

The submit pipeline: manual errors cleared (if clearErrorsOnSubmit), validation runs, submitCount increments, handlers invoked in order. Invalid submissions are always intercepted.

Enables native auto-submit. Every change to a tracked field triggers form.requestSubmit(). Pass { debounce: ms } to delay.

autoSubmit(options?: boolean | AutoSubmitOptions): FormController

Turns auto-submit off and cancels any pending debounce timer. Equivalent to autoSubmit(false).

Chainable fire-and-forget reaction to a field. The callback fires only on changes (not on registration).

Like watch, but fires immediately with the current value and returns an unsubscribe function.

Removes watched callbacks. Three overloads: no args (clear all), field only (clear all for that field), or field + callback (clear one specific watcher).

Registers a listener that fires immediately with the current state and on every subsequent state mutation. Returns an unsubscribe function. Useful for driving a view layer from a single source of truth.

Writes a value into a field and dispatches the correct DOM event so watchers, validators, and visual state run as if a user typed. Returns the controller unchanged when the field does not exist.

Returns the normalized value of a field: string, string[], File[], or undefined.

Returns the underlying DOM field(s) for a given name: a single FormFieldElement, an array (for repeated names like radio/checkbox groups), or null.

Populates the form (or a single field) from the current URL query string. Delegates to setValue, so each prefilled field triggers the normal event pipeline.

Apply an @samline/formatter pipeline to one or more fields inside the bound form. Creates and owns a hidden <input name="<field>Raw"> mirror so FormData/serialize() automatically exposes the raw value.

Alias of format() for readability when field is string[].

Runs validation against the configured validators. Returns { isValid, errors } and marks the form as validated.

Alias of validate kept separate for readability at call sites that want to express “re-run validation now”.

Pushes manual errors into the form. Two overloads: array form (string[], default message “Invalid value.”) and map form (FormErrors, custom messages per field).

Removes manual errors. Validation errors from rules are not touched. Visual attributes are re-synced for the affected fields.

Returns { data, formData } for the form. data is a plain object mirror (repeated names become arrays), formData is a fresh FormData instance. Empty file inputs are filtered out.

Returns a fresh snapshot of the controller state: { values, errors, filledFields, isValid, isValidated, autoSubmit, submitCount }. Pure read — does not notify subscribers.

Inserts a DOM node into the bound form. Useful for rendering banners, hints, or summary blocks that should live inside the <form> element. Returns the created HTMLElement, or null when the controller has no bound form.

function parseFormData(formElement: HTMLFormElement): SerializedFormResult

Same serializer the controller uses internally. Returns { data, formData }. Does not require a controller.

function validateValues(
values: FormValues,
schema: ValidationSchema
): ValidationResult

Runs every field in the schema against a values map. Returns { isValid, errors }.

validateFieldValue(field, value, rules, values)

Section titled “validateFieldValue(field, value, rules, values)”
function validateFieldValue(
field: string,
value: FormFieldValue,
rules: FieldValidationRules,
values: FormValues
): string[]

Runs the rule set against a single value. Returns an array of error messages (empty when the field is valid).

The vanilla entrypoint exports a browser singleton with the same shape as the IIFE bundle’s window.Forms — but as a plain ESM value with no globalThis side-effect. Use it from a bundler when you want the registry ergonomics without the IIFE.

const browser: FormsApi

Module-level singleton. Exposes form, newForm, destroyForm, and available. Spread it into your own globals ({ ...browser, regex }) or call its methods directly. The registry is shared across spreads, so window.Form.available and browser.available always point to the same object. See the Browser registry helpers section in the getting-started guide and FormsApi for the exact shape.

Build a controller via browser.form(id, options) and store it in browser.available[id]. Accepts { id, options }. Logs Form ID is required to console.error and returns undefined if id is missing. Returns the same FormController stored under available[id].

const contact = browser.newForm({
id: 'contact-form',
options: {
validators: { email: { required: true } }
}
})

Look up browser.available[id], call destroy(), and delete the entry. Logs Form ID is required if id is missing, or Form with ID <id> not found if the entry is absent.

browser.destroyForm('contact-form')

Read-only view of the active registry: { [id: string]: FormController }. Iterate it to inspect or invoke methods on every live controller.

for (const controller of Object.values(browser.available)) {
controller.validate()
}

For an equivalent surface in a no-bundler setup, see the Browser global reference.