Form 控制項介紹
Form 用於收集、驗證並提交一組相關欄位,適合申請、登記、設定、資料編輯與流程步驟。它不只是把輸入框排列在一起,還會統一管理欄位分組、版面配置、驗證狀態與提交範圍。
1. Form 功能與設定項目
Form 的設定分為四個層級:
- Form:管理整個表單的版面、模式、資料載入、提交、草稿與公開狀態。
- Form Section:依業務主題組織欄位,也可以設定為可重複的資料集合。
- Field:設定標籤、Field Key、預設值、占列方式、條件行為與驗證規則。
- Button Set / Interaction:透過 Reset、Validate、Submit 與元件函式編排操作。
1.1 屬性與功能速覽
| 設定區域 | 主要屬性或功能 | 用途 |
|---|---|---|
| 基本結構 | ID / Name、Form Sections、Fields、Button Set | 定義 Form 邊界、業務分組與提交範圍 |
| 版面 | Controls Per Row、Form column split、Layout、Label Alignment、Full row | 控制每列欄位數、標籤寬度、排列方式與整列欄位 |
| 模式 | Create、Edit、View、Warn about unsaved changes | 區分新增、編輯、唯讀檢視與未儲存提醒 |
| 資料介接器 | Load / Create / Update URL、Response Data Path、Record ID、Revision | 載入記錄並連接新增、修改介面與樂觀鎖 |
| 提交 | Full values、Changed values only、Custom URL | 提交完整 Form 或只提交變更欄位 |
| 欄位驗證 | Required、Length、Pattern、Number、Custom Validator、Remote validation | 提供即時、遠端與後端欄位錯誤提示 |
| 條件欄位 | Visible / Disabled / Required When、Dependencies、Clear When Hidden | 依其他欄位、Page Context 或目前模式動態調整 |
| 可重複分組 | Collection Key、Minimum / Maximum Items、Add / Delete | 編輯聯絡人或明細列等物件陣列 |
| 草稿 | Browser / Remote storage、Draft Key、Autosave Delay、revision | 自動儲存、恢復或放棄未完成內容 |
| 操作與狀態 | reset、validate、submit、saveDraft、restoreDraft、discardDraft、forms.* | 編排操作並讀取 valid、dirty、submitting 等狀態 |
| 欄位產生 | Business Object、JSON Schema、OpenAPI | 從現有模型快速產生可繼續編輯的欄位結構 |
1.2 表單結構與提交邊界
Form 是欄位狀態與提交範圍的邊界。一個頁面可以放置多個 Form,每個 Form 只管理自己的 Sections、Fields 與 Button Set。
- Form Section 用於表達「基本資料、權限、附件」等業務分組,不只是視覺留白。
- Field Key 是欄位在 Form 狀態與提交 JSON 中的穩定名稱,應與後端 DTO 屬性一致。
- Button Set 負責放置操作;按鈕實際執行 Reset、Validate 或 Submit,仍由 Interaction 設定。
- Submit Form 只收集目標 Form 已註冊的欄位,不會自動混入其他 Form、Page Context 或 Tree Current Record。
如果頁面同時包含搜尋 Form 與編輯 Form,應設定不同 ID,並讓每個操作明確指向正確的 Form。
1.3 版面與回應式行為
Controls Per Row 決定每列最多放幾個欄位,以及單一欄位可用的格線寬度。Form column split 在該區域內分配 Label 和 Content;每列兩個欄位時合計為 12,每列一個欄位時合計為 24。
Layout 支援 Horizontal、Vertical 與 Inline。Label Alignment 只影響 Horizontal 的標籤文字。Full row / Start on new row 讓長欄位獨占整列,但標籤仍與一般欄位第一列對齊。窄螢幕會依閱讀順序堆疊,不需要另建行動版 Form。
1.4 模式、資料載入與提交
| 模式 | 行為 | 常見介面 |
|---|---|---|
| Create | 使用預設值建立新記錄 | Create URL,通常使用 POST |
| Edit | 先載入記錄,再提交修改 | Load URL + Update URL,通常使用 PUT / PATCH |
| View | 復用標籤和值的版面,只讀顯示 | Load URL,不顯示編輯操作 |
Data adapter 透過 Response Data Path 取得記錄,並使用 Record ID Field、Revision Field 保存識別碼與樂觀鎖版本。載入後的值是 Reset 與 Changed values only 的基準。單次提交可使用 Custom URL;需要載入、編輯、衝突檢查或草稿恢復時,應設定完整 Data adapter。
1.5 驗證、欄位錯誤與條件行為
Required、Length、Pattern、Number 與 Custom Validator 提供即時本地驗證。Remote validation 適合由後端檢查信箱、使用者名稱或業務代碼,可設定觸發時機與 Debounce。提交時若後端回傳 fieldErrors,Form 會依 Field Key 把訊息顯示在對應欄位。
Visible When、Disabled When、Required When 可讀取 state.*、context.*、record.* 或 form.*。Dependencies 宣告哪些 Field Key 變更時重新計算;Clear When Hidden 會移除已隱藏的舊值。前端驗證和欄位隱藏不能取代後端驗證與權限。
1.6 可重複分組與草稿
可重複 Form Section 會把內部 Fields 當成一列範本。Collection Key 對應提交 JSON 的物件陣列,Minimum / Maximum Items 限制列數,Runtime 提供 Add / Delete。錯誤路徑保留陣列索引,方便定位實際出錯的記錄。
草稿保存的是尚未提交的 Form 狀態,不是正式業務記錄。Browser storage 適合單一裝置的短期輸入;Remote service 使用 Load / Save URL、Draft Key 與 revision,適合跨裝置或重要流程。revision 衝突必須提示恢復或重新載入,不能靜默覆蓋。
1.7 操作函式與公開狀態
| 操作 | 行為 |
|---|---|
reset | 恢復載入後的基準或 Create 預設值,並清除錯誤 |
validate | 驗證目前 Form;失敗時停止後續操作 |
submit | 驗證、組裝 payload、傳送請求並處理欄位錯誤 |
saveDraft / restoreDraft / discardDraft | 保存、恢復或放棄草稿 |
頁面運算式可以讀取 forms.<formId>.valid、dirty、submitting、submitError、lastSubmit 與 mode。這些狀態是唯讀的。例如 Step 可先執行 Submit Form,成功後才呼叫 nextStep。
1.8 欄位產生與後端協作
Generate fields 可以從 Business Object、JSON Schema 或 OpenAPI Schema 產生 Sections 和 Fields。結果是一般且可編輯的頁面中繼資料,產生後仍要檢查標籤、敏感欄位、選項、權限、版面和介面設定。
資料載入、遠端驗證、草稿與提交請求都會自動攜帶 X-Spark-Page-Environment 和 X-Spark-Page-Render-Mode。後端可以在 DESIGN_PREVIEW 回傳穩定測試資料,在 RUNTIME 執行真實 Use Case;但認證、租戶隔離與權限仍必須另外處理。
1.9 如何選擇設定
| 目標 | 建議起點 | 參考章節 |
|---|---|---|
| 一般新增 Form | Create + Sections + 本地驗證 + Custom URL | 2~8 |
| 編輯既有記錄 | Edit + Load / Update URL + Record ID / Revision | 9、10、14 |
| 唯讀詳細資料 | View + Load URL | 10 |
| 動態欄位 | Conditions + Dependencies | 11、12 |
| 聯絡人或明細列 | Repeatable Group | 13 |
| 長時間輸入 | Draft + 未儲存提醒 | 15 |
| 從模型產生 | Generate fields | 16 |
1.10 Form 中可使用的欄位控制項
先依資料形狀選擇欄位,再設定版面、驗證與 Interaction。元件面板目前可直接加入下列 22 種欄位;舊版 Select、MultiSelect 與舊 MultiRowInput 只保留既有頁面的相容能力,不是新頁面的設定入口。
| 分類 | 欄位控制項 | 適合的資料 |
|---|---|---|
| 基礎輸入 | Input、Address、Text Area | 單行文字、地址與長文字 |
| 選擇與人員 | Select、Radio Button、Checkbox、Switch、Cascade Select、Tree Select、Transfer、User Select、Department Select | 列舉、階層、集合、使用者與部門 ID |
| 日期與數值 | Date Picker、Time Picker、Calendar、Rate、Slider | 日期時間、評分、數值與範圍 |
| 編輯器 | Rich Text、Code Editor、JSON Editor | 帶格式正文、指令碼與 JSON |
| 檔案與結構化資料 | Upload、Multi-Row Input | 檔案中繼資料與物件陣列 |
每個欄位頁面分別說明適用情境、主要屬性、提交值形狀、條件與 Interaction。選擇元件時要以後端資料契約為準,不要只依外觀選擇。
2. 範例:員工到職申請
Spark Sample 的 Form 頁面包含兩個分組、雙欄配置、一個獨占整列的說明欄位,以及 Reset、Validate 和 Submit 三個操作。
Screen
└── Form: Employee Onboarding Form
├── Employee details
│ ├── Full name / Work email / Department
│ └── Employment type / Start date
├── Equipment and access
│ ├── Laptop budget / Administrator access
│ └── Request justification(整列)
└── Reset / Validate / Submit request
3. 新增 Form 與分組
- 把 Form 加入 Screen、Panel、Grid Column、Tab、Step 或 Content。
- 選取 Form,在 Form Sections 新增一個或多個分組。
- 選取分組,在 Fields 新增 Field、Select、RadioBox、DatePicker、Switch、TextArea 等欄位。
- 在 Form 的 Button Set 新增操作按鈕。
- 為 Form 與每個欄位設定穩定的 ID / Name,儲存後同時檢查設計畫布與執行態。
分組應表達「基本資料、權限、附件、確認」等業務意義,不要只為留白而建立空分組。
4. 配置版面
Controls Per Row 決定一列最多放幾個一般欄位。PC 業務表單建議從 2 開始,長文字或窄區域使用 1,3 或 4 只適合短小的搜尋條件。窄螢幕會依閱讀順序堆疊為單欄。
Form 內部使用 24 欄格線,但比例是在「單一欄位可用區域」中計算。Controls Per Row 為 2 時,每個一般欄位占 12 欄:
Label 4 + Content 8 = 12
每列一個欄位時,使用 6 + 18 等合計為 24 的比例。拖曳 Form column split 刻度尺會同步調整 Label 與 Content。
對 TextArea 啟用 Start on new row / Full row 後,它的標籤仍沿用目前 Form 比例並與上一列第一個標籤對齊,內容區會自動跨越剩餘欄位。
| Layout | 用途 |
|---|---|
| Horizontal | 標籤與輸入在同一列,適合 PC 業務表單 |
| Vertical | 標籤位於輸入上方,適合窄容器或長標籤 |
| Inline | 欄位與按鈕連續排列,適合簡短搜尋列 |
5. 依範例配置欄位
| 欄位 | 控制項 | 關鍵設定 |
|---|---|---|
| Full name | Field | Required;Length 2–60 |
| Work email | Field | Required;電子郵件 Pattern |
| Department | Select | 四個固定選項 |
| Employment type | RadioBox | 三個選項 |
| Start date | DatePicker | YYYY-MM-DD |
| Laptop budget | Number Field | 500–5000;Suffix USD |
| Administrator access | Switch | Default Checked 關閉 |
| Request justification | TextArea | 整列;高度 4–8;Length 20–500 |
Name / Field Key 會成為提交 JSON 的屬性名稱。同一個 Form 的可編輯欄位必須使用不同的 Key。
6. 驗證
Required 用於空值,Length 用於文字長度,Pattern 用於電子郵件等格式,Number 用於數值範圍,Custom Validator 用於業務規則。驗證失敗時,Spark 會在對應欄位附近顯示錯誤並停止提交。
前端驗證負責即時回饋,後端仍必須保留等價驗證,因為瀏覽器請求可以繞過頁面。
7. Reset、Validate 與 Submit
Reset 按鈕的 onClick 新增 Call Component Function:
Component: employee_onboarding_form
Function: reset
Reset 會還原初始值並清除驗證訊息。Validate 則新增 Validate Form,並選取同一個 Form。
Submit 設定:
Form: employee_onboarding_form
Submission Mode: Custom URL
URL: /spark/api/sample/form/requests
Method: POST
Spark 先驗證指定 Form,只收集該 Form 已註冊的欄位,再送出 JSON。其他 Form、Page Context 與 Tree Current Record 不會混入請求。
8. Java 後端與頁面上下文
@PostMapping
public ApiResult<FormRequestReceiptDTO> submit(
@RequestBody FormRequestSubmission request,
@RequestHeader(value = SparkPageRequestHeaders.ENVIRONMENT,
required = false) String environment,
@RequestHeader(value = SparkPageRequestHeaders.RENDER_MODE,
required = false) String renderMode) {
SparkPageRequestContext context =
SparkPageRequestHeaders.resolve(environment, renderMode);
return SparkApiResultHelper.success(
Locale.TRADITIONAL_CHINESE,
requestService.submit(request, context),
"SPARK-SAMPLE-FORM-0001");
}
DESIGN_PREVIEW 可回傳穩定但不寫入資料庫的預覽回執,RUNTIME 才執行真正 UseCase。Spark 會集中加入 X-Spark-Page-Environment 與 X-Spark-Page-Render-Mode,不需要在每個 Interaction 重複設定。詳見頁面請求上下文。
9. 進階範例:員工資料編輯
第二個範例涵蓋完整編輯流程:載入記錄、遠端驗證電子郵件、條件式顯示管理員權限原因、增刪緊急聯絡人、自動儲存草稿,以及只提交變更欄位。
可重現頁面位於 form-capabilities-page.json,後端位於 FormCapabilityController 與 FormCapabilitySampleService。
10. 模式與公開狀態
在 Form capabilities 選擇 Create / Edit / View。Edit 由 Load URL 載入並提交至 Update URL;View 保留相同版面但唯讀顯示。也可開啟未儲存變更提醒。
forms.employee_profile_form.valid
forms.employee_profile_form.dirty
forms.employee_profile_form.submitting
forms.employee_profile_form.submitError
forms.employee_profile_form.lastSubmit
forms.employee_profile_form.mode
Form 內可使用 form.dirty、form.submitting。這些狀態為唯讀,不能直接指定。
11. 條件欄位
Visible When: state.adminAccess === true
Required When: state.adminAccess === true
Dependencies: adminAccess
Clear When Hidden: on
Visible / Disabled / Required 可讀取 state.*、context.*、record.* 與 form.* 布林運算式。Dependencies 填寫以逗號分隔的穩定 Field Key。Clear When Hidden 會移除已隱藏的舊值,避免誤提交。
12. 遠端驗證與後端欄位錯誤
在 Work email 的 Validators 新增 Remote validation:
Validation URL: /spark/api/sample/form/validate-email
Method: POST
Debounce: 400
Valid Response Path: data.valid
Message Response Path: data.message
Trigger: blur
新的輸入會取消前一個請求,過期回應不會覆蓋新結果。提交時的業務驗證以 Field Key 回傳錯誤:
{
"success": false,
"fieldErrors": {
"workEmail": ["此電子郵件已被使用。"],
"adminAccessReason": ["請說明需要管理員權限的原因。"]
}
}
Java 使用 SparkFieldValidationException 與 Lattice Message,在 Web 邊界依語言轉換每個欄位訊息。
13. 可重複群組
在 Form Section 開啟 Repeatable Group:
Collection Key: emergencyContacts
Minimum Items: 1
Maximum Items: 3
Add Button Text: Add contact
Section 內欄位成為單列範本,Runtime 管理 Add/Delete 與陣列驗證路徑。View 模式不顯示編輯動作。
14. 資料介接器與差異提交
Load URL: /spark/api/sample/form/records/employee-1001
Create URL: /spark/api/sample/form/records
Update URL: /spark/api/sample/form/records/[[state.id]]
Response Data Path: data
Submission Payload: Changed values only
Record ID Field: id
Revision Field: revision
Edit 載入後建立基準,提交 recordId、revision 與 add/replace/remove 的 changes。Create 始終提交完整值。舊 revision 必須由後端以 HTTP 409 拒絕。
15. 草稿自動儲存
個人臨時輸入使用 Browser storage;跨裝置或重要流程使用 Remote service。設定 Draft Key、Autosave Delay、Load URL、Save URL。按鈕可呼叫 saveDraft、restoreDraft、discardDraft。遠端草稿儲存後必須回傳新的 revision。
16. 從模型或 Schema 產生欄位
在 Form capabilities → Generate fields 選擇 Business Object、JSON Schema 或 OpenAPI,再選 Append 或 Replace。物件陣列會產生 Repeatable Group。結果是一般且可編輯的頁面中繼資料;Runtime 不會執行後端傳回的任意元件 JSON 或腳本。
產生後仍需檢查標籤、敏感欄位、選項、權限、URL 與後端驗證。
17. 常見問題
- 標籤沒有對齊: 每列兩個欄位時使用
4 + 8等合計為 12 的比例。 - 條件欄位沒有更新: Dependencies 填入控制欄位的 Field Key,不要使用顯示標籤。
- 後端錯誤只顯示在頂部: 在頂層
fieldErrors使用完全相同的 Field Key。 - 草稿持續衝突: 每次儲存後,下一個請求必須帶回新的 revision。
- 設計預覽不應建立真實資料: 後端依
DESIGN_PREVIEW分支,回傳預覽結果或使用沙箱。