受注入力

受注を一件読み込んで、編集して、保存する画面です。入力検査の規則はサーバと共用のファイルから取得します。サーバへ返す JSON には、この画面が扱わない項目もそのまま含まれます。

この画面には、項目ごとのハンドラ、送信する JSON を組み立てる処理、Http、URL、サーバのエラー一覧の処理がありません。書いてあるのは次の三つです。

ViewModel

Object subclass: #Vm fields: (custCode. custName. orderDate. qty. unitPrice. urgent. status).

Vm class >> new = Vm fields: {
  custCode: ''. custName: ''. orderDate: (Date year: 2026 month: 1 day: 1).
  qty: 0. unitPrice: 0.00. urgent: false. status: '未処理' }.

初期値が型の宣言です。qty: 0 なら Int、unitPrice: 0.00 なら Decimal、orderDate は Date です。入力欄から来るのは文字列ですが、項目に入れるときにその項目の型として読まれます。別の型の値を入れようとするとコンパイルエラーです。

項目表

Form class >> items = #[
  Item css: 'f-code'   field: 'custCode'  key: 'cust_code'  kind: #text.
  Item css: 'f-qty'    field: 'qty'       key: 'qty'        kind: #text.
  Item css: 'f-status' field: 'status'    key: 'status'     kind: #choice.
  Item css: 'f-urgent' field: 'urgent'    key: 'urgent'     kind: #flag ].

一項目につき一行です。HTML の class 名、ViewModel の項目名、サーバの JSON のキー、入力部品の種類を書きます。HTML の class 名とサーバのキーは別のものなので、この表で対応づけます。

kind で、値をどこから読むかと、どのイベントを受け取るかが決まります。#choice は change イベントを出す <select>、それ以外は input イベントを出す <input> です。

画面

Screen >> typed: text at: field =
  self with: { vm: (vm fieldAt: field put: (Json str: text)) }.

どの項目への入力かはイベントの値として届くので、項目名は実行時の値です。fieldAt:put: で項目名を文字列で指定して書き込みます。キー入力用とチェックボックス用の二つのハンドラで、項目数に関わらずハンドラは増えません。

届いた JSON から ViewModel へ値を入れる処理と、ViewModel から JSON へ書き戻す処理は、それぞれ一行です。

Form class >> fill: vm from: doc = Form items inject: vm into: [:v :i |
  (doc at: i key) isNull ifTrue: [v] ifFalse: [v fieldAt: i field put: (doc at: i key)]].

Form class >> put: vm into: doc = Form items inject: doc into: [:acc :i |
  acc at: i key put: (vm fieldAt: i field)].

サーバへ返す JSON

put:into: は、サーバから届いた JSON に項目を書き込みます。at:put: は書き換えたキー以外を保持するので、id や version のような画面が扱わない項目もそのままサーバへ戻ります。数値は数値、金額は桁を保った Decimal、フラグは真偽値として返ります。

入力検査

保存を押すと、送信する JSON を共通の規則で検査します。規則に引っかかればメッセージが項目の下に表示され、送信されません。通ればサーバへ送られ、サーバは同じ規則で再度検査します。サーバで弾かれた場合は、そのメッセージがページの上部に表示されます。検査の仕組みは入力検査、送信の書き方は通信を書かない画面を参照してください。