keyed_form

Controller

KeyedFormController owns the draft, baseline, validation state, and submit lifecycle.

Comparison copy: this is the previous documentation and may contain outdated guidance. Read the reorganized guides

KeyedFormController<Root> is a pure Dart ChangeNotifier. It owns the immutable draft independently of Flutter widgets.

dart
final form = KeyedFormController<LoginSchema>(
  initialValue: LoginSchema.create(),
  mode: KeyedFormMode.onChange,
  resolver: LoginSchema.validateData,
);

form.seed(userFromApi); // establish a clean baseline
form.field(LoginFields.email).set('alice@example.com');
print(form.isDirty); // true
form.reset(); // restore the baseline

Load data and track edits#

Call seed(value) when loading an existing record. It sets the current value and the comparison baseline together. isDirty tracks whether the draft differs from that baseline; differs(ref) checks one field.

Submit and dispose#

submit(onValid, onInvalid: ...) validates before invoking the async callback. In Flutter, handleSubmit(context, onValid) also reveals and focuses the first invalid field. Dispose the controller with its owning state.

Read state reactively#

Use context.watchField for one value and context.selectForm for a derived slice. KeyedFormSelector scopes the rebuild to a subtree. watchForm and KeyedFormBuilder observe the whole draft, so prefer narrower reads when possible.