Example app
A runnable gallery where every pattern in these docs has a working screen — and the reusable widgets it is built from.
The example/ folder of the repository is a
gallery app: one screen per documented pattern, reachable from the home page. Where the docs and the app ever
disagree, the app wins and the docs get fixed — it is the ground truth.
Run it
git clone https://github.com/leancodepl/advanced_forms.git
cd advanced_forms/example
flutter pub get
flutter runAny Flutter target works; the app uses no platform plugins. It owns its controllers with provider's
ChangeNotifierProvider, which is a choice of the example, not a requirement of the package.
Screen guide
| Screen | Demonstrates | Explained in |
|---|---|---|
| Simple Form | Submit-time validation, an async email check with timeout and failureToError, the hasFailedValidation banner, canSubmit on the button. Try john@email.com (taken) and boom@email.com (the check throws) | Async validation |
| Password Form | Cross-field validation via subscribeToFields, one field opting into ValidationMode.onUnfocus, a custom controller whose error is a List of rule violations | Cross-field logic, Validators |
| Optimized Rendering | Granular rebuilds and the child: optimisation across three layouts of increasing weight | Rendering fields |
| Quiz Form | Applying a server response with setError / setError(null) after the answers are checked | Read-only fields and server errors |
| Complex Form | Single-select dropdowns and swapping the active subform with addSubform / removeSubform | Field controllers, Subforms |
| Delivery List Form | A dynamic list of subforms, validated and disposed by the parent | Subforms |
| Step Form | A multi-page wizard in a PageView: one subform per page, await step.validate() on Next, the parent's validate() on Submit, and a conditional invoice page that setValidationEnabled(false) drops from both the flow and the validation | Subforms |
| Scroll Form | Scrolling to the first invalid field through field.focusNode, plus a plain Stream for one-off UI events | Focus |
Reusable pieces
lib/widgets/— the field widgets the screens share: a text field, a password field, a dropdown, a switch, and threechild:-optimised variants. PlainStatelessWidgets overAdvancedFieldBuilder, ready to copy and restyle. See Reusable field widgets.lib/controllers/password_field_controller.dart— a custom field controller written againstAdvancedTextFieldController, withList<ValidationError>as its error type.test/screens/— widget tests for three of the screens, a template for testing your own forms.
And the examples on this site
Every dart listing framed as a live example in these docs is compiled into a Flutter web bundle when the site is
built and rendered right above its source. They are smaller than the example app's screens on purpose — one lesson
each — and they share nothing with it except the package. Multi-select fields and read-only fields, which the example
app does not cover, have their running examples on Field controllers and
Read-only fields and server errors.
FAQ and gotchas
The questions that come up in review, the type errors that look like package bugs and are not, and the behaviours that surprise on first contact.
Migrating from 0.1.x
leancode_forms 0.1.x to advanced_forms 0.2 — the renames, the behaviour changes that compile but behave differently, and the widget clean-up, in the order to do them.