入力フォームを組む
フォームをセクションに分け、項目を並べる。
入力フォームは form.sections に分けて書く。項目(fields)はセクションの中に入る。
page:
type: form
id: order_entry
title: 受注入力
repository: orderRepository
key: orderNo
form:
sections:
- title: 受注情報
layout: { columns: 2 }
fields:
- { field: orderNo, label: 受注番号, type: text, required: true }
- { field: customer, label: 顧客, type: text, required: true }
- title: 備考
fields:
- { field: note, label: メモ, type: textarea }セクションは1つでもいい
項目が少ないなら分ける必要はない。ただし**fields を form の直下に書くことはできない**(下の「よくある間違い」参照)。セクションが1つでも sections を挟む。
form:
sections:
- fields:
- { field: code, label: コード, type: text }title は省ける
title を書かなければ見出しの無いセクションになる。見出しを付けない使いどころが2つある。
- 項目が少なくて見出しが邪魔なとき
subTable(明細グリッド)を置くセクション — グリッド自身のlabelが見出しになるので、セクション見出しを付けると二重になる
並べ方は layout で変える
layout: { columns: 2 } でセクションごとに1行あたりの項目数を変えられる。住所のような長い項目だけ1列、コードや区分は2〜3列、といった作り方をする。詳しくは「項目の並べ方を変える」に書いた。
form を持てる種別
crud master form detail の4つ。detail は読み取り専用で、form.sections に書いた項目が表示だけされる(入力欄にはならない)。詳細画面のためにレイアウトを別途書かなくていい、という作りになっている。
逆に search dashboard report に form は書けない。wizard はフォームを持つが、form ではなく steps の中に fields を書く。
書けるキー
| キー | 書く場所 | 型 | 必須 | 既定値 | 有効なページ種別 | 説明 |
|---|---|---|---|---|---|---|
form | crudPage | object → form | 任意 | — | crud | The create/edit form. |
form | detailPage | object → form | 任意 | — | detail | The create/edit form. |
form | formPage | object → form | 任意 | — | form | The create/edit form. |
form | masterPage | object → form | 任意 | — | master | The create/edit form. |
sections | form | array → section | 任意 | — | crud detail form master | — |
fields | actionPrompt | array → field | 必須 | — | crud dashboard detail form master report search wizard | What to ask. Ordinary fields: types, required, validators, computed and normalize behave as in a form. |
fields | field | array → field | 任意 | — | crud dashboard detail form master report search wizard | Editor fields for one child row, for type: subTable. Omit to derive inputs from columns. |
fields | field.computed | array of string | 任意 | — | crud dashboard detail form master report search wizard | Fields of the same record to fold (same-record mode). |
fields | section | array → field | 任意 | — | crud detail form master | — |
fields | wizardStep | array → field | 任意 | — | wizard | — |
この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx hatake reference <キー名> で同じものが引ける。
近い例
例は丸ごと写して直すのが一番速い。以下は CI で検証済み(そのまま動く形)。
| ファイル | 種別 | 画面 | どういうときに使うか |
|---|---|---|---|
customer_master.yaml | crud | 顧客マスタ | 検索して一覧に出して、その場で登録・修正・削除まで面倒を見る画面が欲しい |
dept_master.yaml | master | 部門マスタ | コードと名前だけの小さなマスタを、最小の定義でメンテしたい |
customer_detail.yaml | detail | 顧客詳細 | 1件の内容を読み取り専用で表示したい(一覧から開く先) |
customer_form.yaml | form | 顧客入力 | 一覧を持たない単票の入力画面が欲しい(新規と編集を1枚で) |
customer_wizard.yaml | wizard | 顧客登録 | 項目が多いので入力をステップに分けて、1ステップずつ検証したい |
order_entry.yaml | form | 受注入力 | ヘッダと明細行を1画面で入力して、まとめて保存したい |
order_entry_paged.yaml | form | 受注入力(明細別テーブル) | 明細が何百行もあるので、子テーブルから外部キーで引いてページングしたい |
roles_app.yaml | app | 人事管理 | 見せる相手を役割で変えたい(画面ごと隠す・列や項目だけ隠す・押せる人を絞る) |
よくある間違い
form の直下に fields を書く
なぜ駄目か フォームは必ず section で区切る(form が持てるキーは sections だけ)。見出しが要らなければ title を省いた section を1つ置く。
こう直す form.sections[].fields に入れる。
page:
type: form
id: customer_form
title: 顧客入力
repository: customerRepository
form:
fields:
- { field: code, label: コード }page:
type: form
id: customer_form
title: 顧客入力
repository: customerRepository
form:
sections:
- fields:
- { field: code, label: コード }search / wizard / dashboard / report に form を書く
なぜ駄目か form を持つのは crud / master / detail / form だけ。search は読み取り専用、wizard は form ではなく steps、dashboard と report は入力しない。
こう直す 入力もさせたいなら crud(または master)にする。照会と入力を分けたいなら search ページ+detail/form ページにして navigate で繋ぐ。
page:
type: search
id: order_search
title: 受注照会
repository: orderRepository
form:
sections:
- fields:
- { field: orderNo, label: 受注番号 }page:
type: crud
id: order_master
title: 受注保守
repository: orderRepository
table:
columns:
- { field: orderNo, label: 受注番号 }
form:
sections:
- fields:
- { field: orderNo, label: 受注番号 }spec/pitfalls.json から生成。各項目は CI で検証済み(間違いは本当に落ち、正しい方は本当に通る)。手元では npx hatake pitfalls <キー名>。
実物を見る
デモアプリの「受注入力」がこれを使っている。 デモを開く