ReoGrid ReoGrid Web

フォームモード

業務アプリでスプレッドシートを使うとき、実際には「表計算」をしないことがよくあります。レイアウトは固定、ほとんどのセルは保護され、ユーザーは決まった枠に値を埋めるだけ — 帳票アプリのかたちです。v1.6.0 から、この使い方をワークシートの 4 つのスイッチでそのままカバーできます。両エディションで利用できます。

4 つとも描画と操作だけの設定で、xlsx/JSON には保存されません。loadJson や reset のあとに付け直してください。

const ws = grid.worksheet

ws.layoutLocked = true
ws.clickToEdit = true
ws.formNavigation = true
ws.setCellPlaceholder(2, 1, '例: 山田太郎')

レイアウトを固定する

ws.layoutLocked = true

ユーザーによるレイアウト変更を止めます。ヘッダーのドラッグによる列幅・行高の変更、リサイズカーソル、ダブルクリックの自動調整、行・列まるごとの並べ替えドラッグを一括で無効にします。

API からのサイズ変更は従来どおり効くので、テンプレート側のコードは影響を受けません。

ws.column(1).width = 180   // これは効きます

1 回のクリックで編集に入る

ws.clickToEdit = true

編集可能なセルが1 回のクリックで編集に入ります(ダブルクリック不要)。キャレットは既存テキストの末尾に置かれ、対象セルの上ではカーソルが I ビームになるため、見た目も入力欄らしくなります。

保護セルと、文字を置き換えるセル型(チェックボックスなど)は対象外で、従来のクリック動作のままです。


プレースホルダー(ヒント文字)

ws.setCellPlaceholder(2, 1, '例: 山田太郎')

ws.getCellPlaceholder(2, 1)        // '例: 山田太郎' | null
ws.getCellPlaceholderEntries()     // [{ row, column, text }, …]
ws.clearCellPlaceholders()

空のセルに、HTML の input のプレースホルダーのような薄いヒント文字を描きます。

  • セル内に収まり、隣へはみ出しません
  • 数値として右に揃えられることはありません
  • セルの値には含まれず、PDF・印刷・xlsx・JSON にも出ません
  • コメントと同じく、行・列の挿入・削除に追従します

空文字列を渡すと削除できます。


Enter と Tab で入力欄を移動する

ws.formNavigation = true

Enter と Tab が確定したあと「次の入力欄」へ移動し、移動先のエディタを文字が選択された状態で開きます。Shift で逆方向になります。

既定の順序は、編集可能なセルに対する読み順スキャンです。

  • 保護セルを飛ばす
  • 非表示の行と列を飛ばす
  • 結合セルは 1 つの停止点として扱う(アンカー位置)
  • 行の末尾で折り返す — 行の最後の欄から次の行の最初の欄へ自然に続く

これにより、フォームがマウスに触れずに最後まで埋まります。

日本語入力(IME)で数値を入力する場合

IME がオンのとき、変換を確定する Enter は IME のものです。そのため数量や金額の欄では、「120」を確定する Enter と次へ進む Enter の 2 回が必要でした。v1.7.0 からは、formNavigation が有効なとき、確定の Enter でエディタの中身が数値だけになった場合は、そのまま確定して次の欄へ移動します。「3階」のような文字列は従来どおり確定だけなので、確定した後に続けて入力できます。

数値は半角で保存されます。全角の数字(と + - .)を半角にすると数値になる入力 —「120」「-12.5」— は、Excel と同じく 120 / -12.5 としてセルに入るため、数式や小数の入力規則でも数値として扱われます。「3階」のように全角数字を含むだけの文字列は、入力したとおりに保存されます。これはフォームに限らず、セルに入力したすべての値に適用されます。コードから設定した値は、渡したとおりに保存されます。

独自の順序を指定する

固定の帳票テンプレートなど、アプリ側がレイアウトを把握している場合は、ナビゲーターを差し替えて意図した順に項目を巡り、フォームに含まれない編集可能セルを飛ばせます。

const order = [
  { row: 2, column: 1 },
  { row: 2, column: 4 },
  { row: 4, column: 1 },
]

ws.setFormNavigator((from, direction) => {
  const i = order.findIndex(c => c.row === from.row && c.column === from.column)
  return order[i + direction] ?? null   // null = フォームの終わりで止まる
})

// 既定のスキャンに戻す
ws.setFormNavigator(null)

null を返すと、確定だけしてその場に留まります。フォームの終端で望ましい挙動です。

移動せずに移動先だけを知りたい場合は次のようにします。

const next = ws.nextInputCell(2, 1, 1)   // +1 が前方、-1 が後方

入力規則のリストをキーボードで選ぶ

入力規則のリストをキーボードだけで操作できるようになりました。ドロップダウンの項目も同じ流れの中に収まります。

キー動作
編集中の ↓ドロップダウンを開く
選択中の Alt+↓ドロップダウンを開く
開いている間の ↑ / ↓候補を移動
Enterハイライト中の候補を確定
Escape選ばずに閉じる

リストは現在値(空セルなら先頭)の位置で開くので、↓ → Enter の 2 打で選べます。選択はエディタを経由して確定されるため、入力規則の検証もフォーム移動もそのまま効きます。

v1.7.0 からは、▼ ボタンをクリック・タップして選んだ場合も同じ扱いです。Ctrl/Cmd+Z で元に戻せ、formNavigation が有効なら、候補を入力して Enter を押したときと同じように次の欄へ移動します。フォームでない場合は、Excel と同じく選択はそのセルに留まります。


まとめて使う

const ws = grid.worksheet

// 1. 全体を保護し、入力セルだけロックを外す
ws.protected = true
ws.range('C3:C8').setLock('unlocked')

// 2. フォームとしての振る舞い
ws.layoutLocked = true
ws.clickToEdit = true
ws.formNavigation = true

// 3. ヒント
ws.setCellPlaceholder(2, 2, '例: 山田太郎')
ws.setCellPlaceholder(3, 2, '例: 03-1234-5678')

// 4. ドロップダウンの項目
ws.range('C5').setValidation({ type: 'list', options: ['東京', '大阪', '名古屋'] })

ユーザーは最初の欄をクリックして入力し、Enter を押すだけで、フォームの最後まで進めます。


保存されません

layoutLocked・clickToEdit・formNavigation、設定したナビゲーター、そしてすべてのプレースホルダーは画面の状態です。xlsx にも ReoGrid JSON にも書き出されません。

読み込み時の扱いは項目によって違います。loadJson() や reset() はセルの内容と一緒にプレースホルダーを消しますが、3 つのスイッチとナビゲーターはワークシートオブジェクトに元の値のまま残ります。ページを開き直せばどれも設定されていない状態から始まり、別のシートがアクティブになる読み込みでは、そのシートには設定がありません。全部をホスト側の 1 つの関数にまとめ、読み込みのたびに実行してください。2 回実行しても問題ありません。

function applyFormMode(ws) {
  ws.layoutLocked = true
  ws.clickToEdit = true
  ws.formNavigation = true
  ws.setCellPlaceholder(2, 2, '例: 山田太郎')
  // ……使うなら setFormNavigator() も
}

grid.loadJson(doc)
applyFormMode(grid.worksheet)   // 読み込み後は grid.worksheet を取り直す

保護そのもの(シートの保護フラグとロックを外したセル)と入力規則は ReoGrid JSON に含まれるので、JSON の往復で入力欄は残ります。xlsx はシート保護もロック状態も保持しません。


関連ページ

このページは役に立ちましたか?
ニュースレター

開発の最新情報をお届けします

新しいリリース・機能追加・お知らせをいち早く受け取るには、
メーリングリストにご登録ください。