Orbit Form Builder
Visually build Orbit forms from every field and layout, then collect answers with handlers.
pip install almasix-orbit-form-builder- Installs—
- Stars1
- Author
- Almasix
- Orbit versions
- 0.5
- Package
- almasix-orbit-form-builder
- License
- MIT
- Python
- >=3.11
- Listed
- September 28, 2026
What it does
Design dynamic forms inside your Orbit panel using the full Orbit field and layout catalog. Publish a definition, share a fill page, and store answers with optional email, webhook, or custom callable handlers. Multi-tenant panels keep definitions and submissions scoped by tenant.
Install
pip install almasix-orbit-form-builder
from almasix_orbit_form_builder import FormBuilderPlugin, bootstrap_memory_store
bootstrap_memory_store()
panel.plugin(FormBuilderPlugin.make().navigation_group("Forms"))
Full README: almasix-orbit-form-builder.

Documentation
View sourceOrbit Form Builder
Visually build Orbit forms from every Orbit field and layout, publish them, and collect answers with pluggable handlers.
Install
pip install almasix-orbit-form-builder
Register the plugin on a panel:
from almasix_orbit_form_builder import FormBuilderPlugin, bootstrap_memory_store
bootstrap_memory_store() # or DatabaseFormStore() after migrating
panel.plugin(FormBuilderPlugin.make().navigation_group("Forms"))
For database storage, create the tables from almasix_orbit_form_builder.migrations.migration_statements() and:
from almasix_orbit_form_builder import DatabaseFormStore, set_form_store
set_form_store(DatabaseFormStore())
Requires almasix-orbit ≥ 0.5.3 (custom pages mount Conduit hosts via get_conduit_host()).
What you get
| Surface | Purpose |
|---|---|
| Form builder page | Generous visual canvas (grids/fields look like themselves), filterable component bank, drag-drop with drop-zone highlights, property modal, preview modal with live validation, draft/publish |
| Definitions resource | List metadata (JSON is readonly — edit structure on the builder page) |
| Submissions resource | Inspect answers |
Fill page (/forms/fill) | Respondents submit published forms |
Designer
- Filter or browse the Components bank; drag onto the canvas or into a layout drop zone (or click to add into the selection).
- Root fields follow Form columns (default 2). Nested Grid / Group show their own column count.
- Click a field or layout (or Edit) to open the properties modal — label, placeholder, validation rules, columns, etc.
- Preview opens a modal with a fillable form (validates; does not store).
- JSON / Handlers are optional drawers — definition JSON stays a readonly export.
Definitions
Forms are stored as JSON that mirrors Orbit’s to_dict() shape:
{
"components": [
{
"type": "Section",
"heading": "Contact",
"schema": [
{
"type": "Grid",
"columns": 2,
"schema": [
{ "type": "TextInput", "name": "email", "label": "Email", "required": true },
{ "type": "TextInput", "name": "phone", "label": "Phone" }
]
}
]
}
]
}
build_form(definition) hydrates that document into a live almasix.orbit.forms.Form. Callables (relationship loaders, live hooks) are not embedded in JSON — register named handlers in your app and reference them from field config when needed.
Answer handlers
Every submit is always persisted first. Then configured handlers run in order. Configure them in the designer (store / email / webhook / callable), for example:
{
"handlers": [
{ "type": "store" },
{ "type": "email", "to": "ops@example.com", "subject": "New lead" },
{ "type": "webhook", "url": "https://example.com/hooks/forms" },
{ "type": "callable", "name": "my_crm" }
],
"success_message": "Thanks — we got it."
}
from almasix_orbit_form_builder import register_handler
def push_to_crm(form, submission, config): ...
register_handler("my_crm", push_to_crm)
Tenancy
When the panel has tenancy enabled, the plugin binds set_tenant_resolver so definitions and submissions are keyed by tenant_id (empty string = global). Use .without_tenant_resolver() to skip.
Limits
- Designer is a nested tree with drag-drop (not a free-form pixel canvas).
- Relationship / upload-heavy fields work with static serializable props; advanced callables need named handlers.
- Fill page lives at
forms/fill— setform_slugon the host (or open via the UI) for the published slug.
License
MIT
This plugin is maintained by the Orbit team.
How to install and wire a plugin: Using a plugin. Report security issues on theadvisory form.