@gluonjs/molecules / packages/molecules/src / FormController
Interface: FormController<Values, Result>
Type Parameters
Values
Values extends Record<string, unknown>
Result
Result = void
Properties
state
readonlystate:FormState<Values>
Methods
clearErrors()
clearErrors():
void
Returns
void
dispose()
dispose():
void
Returns
void
hydrate()
hydrate(
snapshot):void
Parameters
snapshot
FormSnapshot<Values>
Returns
void
register()
register<
Name>(name):FormFieldBinding<Values,Name>
Type Parameters
Name
Name extends string
Parameters
name
Name
Returns
FormFieldBinding<Values, Name>
reset()
reset(
values?):void
Parameters
values?
Values
Returns
void
setError()
setError<
Name>(name,error?):void
Type Parameters
Name
Name extends string
Parameters
name
Name
error?
string
Returns
void
setTouched()
setTouched<
Name>(name,touched?):void
Type Parameters
Name
Name extends string
Parameters
name
Name
touched?
boolean
Returns
void
setValue()
setValue<
Name>(name,value):void
Type Parameters
Name
Name extends string
Parameters
name
Name
value
Values[Name]
Returns
void
snapshot()
snapshot():
FormSnapshot<Values>
Returns
FormSnapshot<Values>
submit()
submit(
options?):Promise<FormSubmitResult<Result>>
Parameters
options?
Returns
Promise<FormSubmitResult<Result>>
subscribe()
subscribe(
listener): () =>void
Parameters
listener
FormListener<Values>
Returns
() => void
validate()
validate(
options?):Promise<boolean>
Parameters
options?
Returns
Promise<boolean>
Example
Consume the controller that coordinates typed field state, validation, submission, and SSR restoration:
import { createFormController, type FormController, type FormControllerOptions, type FormErrors, type FormFieldBinding, type FormFieldName, type FormListener, type FormOperationOptions, type FormSnapshot, type FormState, type FormSubmitHandler, type FormSubmitResult, type FormTouched, type FormValidationContext, type FormValidator } from '@gluonjs/molecules';
type Profile = { email: string; name: string };
type SubmitResult = { id: string };
const validate: FormValidator<Profile> = (values, context) => values.email.includes('@') ? {} : { email: 'Enter a valid email.' };
const submit: FormSubmitHandler<Profile, SubmitResult> = async (values, context) => ({ id: values.email });
const options = { initialValues: { email: '', name: '' }, validate, onSubmit: submit } satisfies FormControllerOptions<Profile, SubmitResult>;
const controller: FormController<Profile, SubmitResult> = createFormController(options);
const email: FormFieldBinding<Profile, 'email'> = controller.register('email');
const fieldName: FormFieldName<Profile> = email.name;
const errors: FormErrors<Profile> = controller.state.errors;
const touched: FormTouched<Profile> = controller.state.touched;
const state: FormState<Profile> = controller.state;
const listener: FormListener<Profile> = (nextState) => console.log(nextState.dirty);
const context: FormValidationContext<Profile> = { values: state.values, touched, signal: new AbortController().signal };
const operation: FormOperationOptions = { signal: context.signal };
const snapshot: FormSnapshot<Profile> = controller.snapshot();
const result: FormSubmitResult<SubmitResult> = await controller.submit(operation);
controller.subscribe(listener);
controller.hydrate(snapshot);
console.log(fieldName, errors, context.signal.aborted, result.ok);
controller.dispose();