How osamaalhimyari/frappe_form works
1. Repository purpose
- This is a Flutter package named around frappe_form that renders a Frappe DocType form UI, applies field-level behavior/validation, and converts user input into a response payload.
- It is not a full app; the real product is the reusable library in lib/, with a separate example/ Flutter app used to demonstrate and validate behavior across platforms.
2. Public package boundary
- The main package entrypoint is lib/frappe_form.dart.
- The package exposes a form-rendering surface centered on DocFormView, plus supporting entities, controllers, and widget overrides so consumers can embed the form into their own app and customize some field behaviors.
3. Core data model layer
- lib/src/entity/ contains the schema objects that represent the Frappe form definition: DocForm, DocField, DocType, DocGeolocation, and enumerations for field/type metadata.
- lib/src/model/ holds runtime/user-input models such as DocFieldAnswer, DocFieldBundle, attachments, dependency controllers, render rules, and some newer domain models like dashboard and transaction objects.
- The presence of *.g.dart files indicates code generation is used for serialization and/or boilerplate reduction.
4. Form orchestration and business logic
- lib/src/logic/doc_form_controller.dart and doc_field_group_controller.dart coordinate the form lifecycle, field grouping, dependency evaluation, and response assembly.
- The logic/enumerator/ folder defines how dependency expressions are interpreted, including arithmetic, behavior, condition, and operator handling for “depends on” rules.
- Utility helpers under logic/utils/ provide reusable conversion and evaluation support for booleans, dates, numbers, text, time, iteration, and parameter handling.
5. Presentation layer architecture
- lib/src/presentation/widgets/ contains the actual UI for the form and its field renderers.
- doc_form_view.dart is the main composite widget; doc_form_loading_view.dart handles loading state.
- Field rendering is split by capability and field family: base, text input, choice, date, boolean, attachment, location, display, group, and the newer custom field set.
6. Field-to-widget mapping
- The architecture is essentially a dispatcher: each DocField.type maps to a dedicated widget implementation.
- Examples include text editors, phone input, date/time pickers, HTML rendering, select/radio/check controls, geolocation, signatures, attachments, and table/group layouts.
- This makes the form renderer extensible without changing the entire form container.
7. Customization hook for unsupported or special fields
- DocFormController exposes an onBuildFieldView hook used to override or inject custom widgets for specific field types.
- The README example shows this being used for dashboard-style custom fields like heatmaps and connections, which are not part of the core Frappe field set but are supported through application-level overrides.
8. Localization and validation
- lib/src/presentation/localization/ provides English and Spanish defaults plus a base localization contract for extension.
- Validation and formatting utilities live under presentation/utils/, keeping input formatting, keyboard behavior, phone formatting, and validation messages separate from field widgets.
- The form view uses these utilities to enforce required fields, read-only behavior, and dependency-based visibility/mandatory rules.
9. External capability boundaries
- Some functionality is intentionally delegated to the host app rather than embedded in the package, especially attachment loading and dynamic link suggestion lookup.
- The README also shows link and HTML rendering can rely on external plugins/services such as url_launcher and webview-based editors, but the package keeps those as UI integrations rather than owning backend access.
10. Platform strategy
- The package is designed for Flutter’s cross-platform runtime and is exercised on Android, iOS, web, macOS, Linux, and Windows via the example/ app.
- The repo includes generated platform scaffolding plus web build artifacts under docs/, suggesting the package is also published with a Flutter web documentation/demo build.
11. Example application as the integration reference
- example/lib/main.dart and its helper files show the intended consumption pattern: load a DocForm, provide callbacks like onSubmit, onCancel, onResponse, fetchSuggestions, and custom field builders, then render DocFormView.
- This example app is effectively the architecture reference for consumers, demonstrating how dynamic link resolution, attachment handling, and custom field rendering flow through the package API.
12. Generated and build support
- build.yaml, analysis_options.yaml, and the *.g.dart files indicate a codegen-oriented workflow.
- The docs/ directory contains compiled Flutter web assets and service worker/bootstrap files, which are deployment artifacts rather than source architecture, but they confirm the package is built and distributed with a web demo/documentation target in mind.
Main entry points: doc_field_view.dart Field Dispatcher · doc_form_controller.dart Form Controller · doc_form_view.dart Form View · frappe_form.dart frappe_form.dart
Components 21
Public API
Package entrypoints and consumer-facing surface
- frappe_form.dart · Exports the library surface for consumers
lib/frappe_form.dart
Core Library
Domain model, orchestration, and rendering internals
- Form View · Main form UI that renders and wires the entire doc form
lib/src/presentation/widgets/doc_form_view.dart - Loading View · Loading and placeholder presentation for the form
lib/src/presentation/widgets/doc_form_loading_view.dart - Form Controller · Owns lifecycle, response assembly, and field customization hooks
lib/src/logic/doc_form_controller.dart - Group Controller · Coordinates grouped fields and grouped field state
lib/src/logic/doc_field_group_controller.dart - Depends Logic · Evaluates dependency expressions and operators for field behavior
lib/src/logic/enumerator/doc_field_depends_on_operator.dart - Logic Utils · Reusable boolean, date, number, text, time, iterable, and param helpers
lib/src/logic/utils/num_utils.dart - Form Schema · Frappe form definition objects such as DocForm, DocField, and DocType
lib/src/entity/doc_form.dart - Schema Enums · Field, doc type, geometry, and feature metadata enumerations
lib/src/entity/enumerator/field_type.dart - Runtime Models · User-input bundles, answers, attachments, render rules, and dependency state
lib/src/model/doc_field_answer.dart - New Models · Dashboard, message, transaction, and special field-name models
lib/src/model/new_models/dashboard.dart - Localization · Default English and Spanish localization contracts
lib/src/presentation/localization/doc_form_localization.dart - Presentation Utils · Formatting, keyboard, phone, and validation helpers for widgets
lib/src/presentation/utils/validation_utils.dart - Field Dispatcher · Maps field types to dedicated widget implementations
lib/src/presentation/widgets/doc_field_item/base/doc_field_view.dart - Text Fields · Text, numeric, password, URL, phone, markdown, and editor variants
lib/src/presentation/widgets/doc_field_item/text_input/doc_field_text_view.dart - Choice Fields · Select, radio, checkbox, and open-choice controls
lib/src/presentation/widgets/doc_field_item/choice/doc_field_select_view.dart - Date & Bool · Date/time pickers and boolean toggles
lib/src/presentation/widgets/doc_field_item/date/doc_field_date_time_view.dart - Media & Location · Attachments, signatures, geolocation, and related field views
lib/src/presentation/widgets/doc_field_item/location/doc_field_geolocation_view.dart - Display & Groups · HTML, headings, sections, tables, tabs, columns, and list layouts
lib/src/presentation/widgets/doc_field_item/group/doc_field_table_view.dart - Custom Fields · Application-specific field views such as dashboard, link, barcode, color, and multi-select
lib/src/presentation/widgets/new_fields/dashboard/heat_map_view.dart
Example App
Cross-platform integration reference
- Example Main · Example app entrypoint showing how to embed and configure the form
example/lib/main.dart
Connections 23
- frappe_form.dart → Form View: exports · Package entrypoint exposes the main form surface
- frappe_form.dart → Form Schema: exports · Public API includes schema objects
- frappe_form.dart → Runtime Models: exports · Public API includes runtime answer/model types
- Form View → Form Controller: uses · View delegates lifecycle and submission coordination
- Form View → Loading View: shows · Switches to loading state while data is unavailable
- Form View → Field Dispatcher: renders · Builds field widgets through the type dispatcher
- Form Controller → Group Controller: coordinates · Controller manages grouped field orchestration
- Form Controller → Depends Logic: evaluates · Applies dependency expressions for visibility and requirements
- Form Controller → Presentation Utils: validates · Uses formatting and validation helpers for input behavior
- Form Controller → Localization: labels · Reads localized strings for validation and UI text
- Form Controller → Runtime Models: assembles · Collects answers and builds response payloads
- Form Schema → Schema Enums: classified by · Schema objects are parameterized by enumerated metadata
- Runtime Models → Form Schema: binds to · Runtime answers are shaped by schema definition
- Field Dispatcher → Text Fields: delegates · Routes text-like fields to specialized inputs
- Field Dispatcher → Choice Fields: delegates · Routes choice-based fields to selection widgets
- Field Dispatcher → Date & Bool: delegates · Routes date and boolean fields to dedicated controls
- Field Dispatcher → Media & Location: delegates · Routes media, attachment, and location fields
- Field Dispatcher → Display & Groups: delegates · Routes structural and display-only field families
- Field Dispatcher → Custom Fields: extends · Supports host-app overrides and special field renderers
- Custom Fields → Form Controller: hooked by · Custom field builders are injected through the controller hook
- Example Main → frappe_form.dart: imports · Example app consumes the package entrypoint
- Example Main → Form View: builds · Example composes the main form widget in a host app
- Example Main → Custom Fields: overrides · Demonstrates custom builders for unsupported field types