Forms define data entry layouts and configurations for creating and editing records. They control which fields are visible, their validation rules, and the user experience for data input.
File Naming Convention: <form_name>.form.yml
The filename (without the .form.yml extension) automatically becomes the form's identifier. This eliminates the need for a redundant name property inside the file.
Examples:
project_create.form.yml → Form identifier: project_create
customer_edit.form.yml → Form identifier: customer_edit
quick_task.form.yml → Form identifier: quick_task
Files should use snake_case for multi-word names.
Property Type Required Description labelstringRequired Human-readable form title (e.g., "Create Project"). objectstringRequired Object this form creates/edits. typestringOptional Form type: create, edit, clone, wizard. Default: create. descriptionstringOptional Internal description of the form purpose. sectionsarrayRequired Form sections containing fields. layoutobjectOptional Layout configuration (columns, spacing, etc.). validationobjectOptional Additional validation rules. actionsobjectOptional Form action buttons configuration. defaultsobjectOptional Default field values. read_only_fieldsarrayOptional Fields that cannot be edited. hidden_fieldsarrayOptional Fields hidden from user but included in submission. permissionsobjectOptional Access control for the form. ai_contextobjectOptional AI-friendly context for understanding form purpose.
Form for creating new records.
# File: project_create.form.yml
label : Create Project
object : project
type : create
sections :
# Basic Information
- label : Project Information
fields :
- name :
required : true
placeholder : Enter project name
- description :
type : textarea
rows : 4
- status :
default : planning
- owner :
default : $current_user.id
# Timeline
- label : Timeline
fields :
- start_date :
default : $today
- end_date :
required : true
validation :
min : $field.start_date
# Budget
- label : Budget
fields :
- budget_amount :
format : currency
required : true
- budget_category :
type : select
options :
- capital
- operational
- research
# Default values
defaults :
status : planning
priority : medium
owner_id : $current_user.id
# Form actions
actions :
submit :
label : Create Project
on_success :
redirect : /projects/:id
message : Project created successfully
cancel :
label : Cancel
redirect : /projects
ai_context :
intent : "Form for creating new projects with timeline and budget"
domain : project_management
Form for modifying existing records.
# File: customer_edit.form.yml
label : Edit Customer
object : customer
type : edit
sections :
- label : Basic Information
fields :
- name
- email
- phone
- company
- label : Address
columns : 2
fields :
- street
- city
- state
- zip_code
- label : Classification
fields :
- industry
- tier
- account_manager
# Read-only fields
read_only_fields :
- created_at
- created_by
- id
# Actions
actions :
submit :
label : Save Changes
on_success :
message : Customer updated successfully
stay_on_page : true
delete :
label : Delete Customer
confirm : Are you sure you want to delete this customer?
permission : delete_customer
ai_context :
intent : "Edit existing customer information"
domain : crm
Form for duplicating records with modifications.
# File: project_clone.form.yml
label : Clone Project
object : project
type : clone
# Fields to clone (others excluded)
clone_fields :
- name
- description
- status
- budget_amount
- owner
sections :
- label : New Project Details
fields :
- name :
label : New Project Name
required : true
default : $source.name + " (Copy)"
- description :
default : $source.description
- start_date :
required : true
default : $today
- end_date :
required : true
# Exclude from clone
exclude_fields :
- id
- created_at
- created_by
- tasks # Don't clone related tasks
ai_context :
intent : "Clone project with modified timeline and name"
domain : project_management
Multi-step form for complex data entry.
# File: employee_onboarding.form.yml
label : Employee Onboarding
object : employee
type : wizard
steps :
# Step 1: Personal Information
- label : Personal Information
description : Basic employee details
sections :
- fields :
- first_name
- last_name
- email
- phone
- date_of_birth
# Step 2: Employment Details
- label : Employment Details
description : Job and compensation information
sections :
- label : Position
fields :
- job_title
- department
- manager
- start_date
- label : Compensation
fields :
- salary
- employment_type
- pay_frequency
# Step 3: Benefits
- label : Benefits Selection
description : Choose benefit options
sections :
- fields :
- health_insurance
- dental_insurance
- retirement_plan
- pto_days
# Step 4: Documents
- label : Documents
description : Upload required documents
sections :
- fields :
- resume :
type : file
accept : .pdf,.doc,.docx
- id_document :
type : file
required : true
# Wizard navigation
navigation :
show_progress : true
allow_back : true
validate_step : true # Validate before proceeding
actions :
submit :
label : Complete Onboarding
on_success :
redirect : /employees/:id
message : Employee onboarding completed
ai_context :
intent : "Multi-step wizard for comprehensive employee onboarding"
domain : hr
Sections organize fields into logical groups.
sections :
# Basic section
- label : Contact Information
fields :
- name
- email
- phone
# Section with columns
- label : Address
columns : 2
fields :
- street
- city
- state
- zip_code
# Collapsible section
- label : Additional Details
collapsible : true
collapsed : true
fields :
- notes
- tags
# Conditional section
- label : Shipping Details
visible_when :
field : needs_shipping
operator : "="
value : true
fields :
- shipping_address
- shipping_method
fields :
- name :
label : Project Name
required : true
placeholder : Enter project name
help_text : Choose a descriptive name
max_length : 100
- description :
type : textarea
rows : 4
max_length : 1000
- status :
type : select
options :
- value : planning
label : Planning
- value : active
label : Active
- value : completed
label : Completed
default : planning
- start_date :
type : date
required : true
min : $today
default : $today
- budget :
type : number
format : currency
min : 0
step : 100
fields :
# Text inputs
- name :
type : text
- email :
type : email
- phone :
type : phone
- url :
type : url
# Numeric inputs
- quantity :
type : number
min : 0
max : 1000
- price :
type : currency
- percentage :
type : percent
# Date/Time
- due_date :
type : date
- meeting_time :
type : datetime
- duration :
type : time
# Selection
- category :
type : select
options : [ option1 , option2 ]
- tags :
type : multiselect
options : [ tag1 , tag2 , tag3 ]
- priority :
type : radio
options : [ low , medium , high ]
- features :
type : checkbox_group
options : [ feature1 , feature2 ]
# Boolean
- is_active :
type : checkbox
default : true
- accept_terms :
type : toggle
# Text areas
- description :
type : textarea
rows : 5
- notes :
type : richtext
# Relationships
- owner :
type : lookup
reference_to : users
searchable : true
- related_projects :
type : master_detail
reference_to : projects
# Files
- attachment :
type : file
accept : .pdf,.doc
max_size : 5242880 # 5MB
- photos :
type : file
multiple : true
accept : image/*
Show/hide fields based on other field values.
fields :
- event_type :
type : select
options :
- in_person
- virtual
- hybrid
- venue_address :
visible_when :
field : event_type
operator : in
value : [ in_person , hybrid ]
- video_link :
visible_when :
field : event_type
operator : in
value : [ virtual , hybrid ]
required_when :
field : event_type
operator : "="
value : virtual
fields :
- email :
type : email
required : true
validation :
format : email
message : Please enter a valid email address
- age :
type : number
validation :
min : 18
max : 120
message : Age must be between 18 and 120
- username :
type : text
validation :
pattern : ^[a-z0-9_]{3,20}$
message : Username must be 3-20 characters, lowercase letters, numbers, and underscores only
validation :
# End date must be after start date
- rule : date_range
fields : [ start_date , end_date ]
condition :
field : end_date
operator : ">"
compare_to : start_date
message : End date must be after start date
# Conditional requirement
- rule : conditional_required
when :
field : needs_approval
operator : "="
value : true
then :
required : [ approver , approval_reason ]
validation :
# Custom validation function
- rule : custom
name : check_budget_limit
message : Budget exceeds department limit
function : |
async function validate(data, context) {
const dept = await context.repo.findOne('department', data.department_id);
return data.budget <= dept.budget_limit;
}
layout :
columns : 2
gap : 16
sections :
- label : Contact Details
fields :
- name # Spans 2 columns by default
- email :
columns : 1 # Takes 1 column
- phone :
columns : 1 # Takes 1 column
layout :
desktop :
columns : 2
tablet :
columns : 1
mobile :
columns : 1
sections :
- label : Important Notice
style :
background : warning
padding : 16
border : true
fields :
- important_note
actions :
# Primary submit button
submit :
label : Save
icon : standard:save
variant : primary
on_success :
message : Record saved successfully
redirect : /objects/:object/:id
# Secondary cancel button
cancel :
label : Cancel
variant : secondary
redirect : /objects/:object
# Additional action
save_and_new :
label : Save & New
on_success :
message : Record saved
redirect : /objects/:object/create
actions :
# Custom save with approval
submit_for_approval :
label : Submit for Approval
variant : primary
before_save :
- set_field :
status : pending_approval
- call_action :
action : send_approval_notification
on_success :
message : Submitted for approval
redirect : /objects/:object/:id
# File: contact_create.form.yml
label : Create Contact
object : contact
type : create
sections :
# Basic Information
- label : Basic Information
fields :
- first_name :
required : true
placeholder : First Name
- last_name :
required : true
placeholder : Last Name
- email :
type : email
required : true
validation :
format : email
- phone :
type : phone
format : (###) ###-####
# Company Details
- label : Company
fields :
- account :
type : lookup
reference_to : accounts
required : true
searchable : true
- title :
placeholder : Job Title
- department :
type : select
options :
- Sales
- Marketing
- Engineering
- Support
# Address
- label : Address
columns : 2
collapsible : true
fields :
- street
- city
- state
- zip_code
defaults :
status : active
owner_id : $current_user.id
actions :
submit :
label : Create Contact
on_success :
message : Contact created successfully
redirect : /contacts/:id
cancel :
label : Cancel
redirect : /contacts
ai_context :
intent : "Create new business contact with company association"
domain : crm
# File: order_entry.form.yml
label : New Order
object : order
type : create
sections :
# Customer Selection
- label : Customer
fields :
- customer :
type : lookup
reference_to : customers
required : true
searchable : true
on_change :
- populate_field :
shipping_address : $selected.default_address
# Order Items
- label : Order Items
type : line_items
relationship : order_items
fields :
- product :
type : lookup
reference_to : products
required : true
- quantity :
type : number
min : 1
default : 1
- unit_price :
type : currency
readonly : true
auto_populate : $product.price
- total :
type : formula
formula : quantity * unit_price
readonly : true
# Shipping
- label : Shipping
fields :
- shipping_address :
type : address
required : true
- shipping_method :
type : select
options :
- Standard
- Express
- Overnight
default : Standard
- requested_delivery :
type : date
min : $today + 2
# Validation
validation :
- rule : minimum_order
condition :
formula : order_items.sum(total) >= 100
message : Minimum order amount is $100
# Totals (calculated)
calculated_fields :
subtotal :
formula : order_items.sum(total)
tax :
formula : subtotal * 0.08
shipping_cost :
formula : |
shipping_method === 'Standard' ? 10 :
shipping_method === 'Express' ? 25 : 50
total :
formula : subtotal + tax + shipping_cost
actions :
submit :
label : Place Order
on_success :
message : Order placed successfully
send_email :
to : $customer.email
template : order_confirmation
redirect : /orders/:id
ai_context :
intent : "Create sales order with line items and shipping details"
domain : e-commerce
# File: task_quick.form.yml
label : Quick Task
object : task
type : create
description : Simplified form for quick task creation
# Single section, minimal fields
sections :
- fields :
- title :
required : true
placeholder : What needs to be done?
autofocus : true
- due_date :
type : date
default : $today + 7
- priority :
type : select
options : [ Low , Medium , High ]
default : Medium
# Auto-populate fields
defaults :
status : todo
assignee_id : $current_user.id
project_id : $context.project_id # From URL context
# Quick save
actions :
submit :
label : Create Task
on_success :
message : Task created
close_modal : true
refresh_list : true
ai_context :
intent : "Quick task creation form for minimal friction"
domain : task_management
use_cases :
- "Create task from email"
- "Add task during meeting"
- "Quick capture from mobile"
Logical grouping : Organize related fields into sections
Progressive disclosure : Use collapsible sections for optional fields
Clear labels : Use descriptive field labels and help text
Smart defaults : Pre-fill fields when possible
Inline validation : Validate as user types, not just on submit
Lazy load options : Load lookup options on demand
Optimize dependencies : Minimize field dependencies
Debounce validation : Don't validate on every keystroke
Cache lookups : Cache frequently used lookup data
Keyboard navigation : Support tab order and keyboard shortcuts
Screen reader friendly : Use proper labels and ARIA attributes
Focus management : Set autofocus appropriately
Error messages : Clear, actionable error messages
Server validation : Always validate on server, not just client
CSRF protection : Include CSRF tokens in forms
Sanitize inputs : Prevent XSS and injection attacks
Permission checks : Verify user can create/edit before showing form
Forms integrate with:
Objects : Use object field definitions
Validation : Apply object validation rules
Permissions : Respect field-level permissions
Actions : Trigger actions on form events
Hooks : Fire hooks on create/update
Formulas : Calculate formula fields in real-time
ai_context :
# Business purpose
intent : "Simplified lead capture form for trade shows"
# Domain
domain : sales
# Use cases
use_cases :
- "Capture leads at events"
- "Quick data entry from mobile"
- "Minimal friction lead generation"
# Form characteristics
characteristics :
- "Minimal fields for speed"
- "Mobile-optimized layout"
- "Offline capable"